Why is import statement not needed in this instance? - java

Why does Java allow me to exclude the import statement for MyClass in the following case. Also there must not be any other explicit declarations of MyClass in the rest of the class. It seems like javac should not allow the import to be missing.
public class MyClassDao {
public List<MyClass> getAll(){....}
}
// no import needed here for MyClass
public class RandomService {
....
void process(){
myModel.setMyClassList(myClassDao.getAll());
}
}

As the Java Language Specification states
An import declaration allows a named type or a static member to be
referred to by a simple name (ยง6.2) that consists of a single
identifier.
You are not referring to the name MyClass, so no import statement is needed.

Related

When I have an enum defined in the same source file as the class that uses it, why is an import of the enum needed?

If a source file defining a class also defines an enum used by the class (and users of the class), why does the source file require an import of that enum? I am using Netbeans 8.2 by the way.
Here is a simple example:
// file and class name Foo, enum name Bar
package pak;
import pak.Foo.Bar; // <-- why is this required?
public class Foo {
public static enum Bar { ZOT,BIF };
public Foo() {}
public void doFooBar(Bar op) { /* whatever */ }
}
Referring to the simple example above, the Netbeans compiler insists I include the import of the enum.
Why do I need to import when the enum is in the same source file as the class?

Java import wildcard accessibility for nested static classes

How does the java accessibility (or perhaps, scope) work with respect to type import multi-level nested classes? An example:
ClassA.java:
package com.oracle.javatests;
public class ClassA {
public static class NestedAA {
public void printSomething() {
System.out.println("inside " + this.getClass().getName());
}
public static class NestedAB{
public void printSomethingAB() {
System.out.println("inside " + this.getClass().getName());
}
}
}
public void printSomething() {
System.out.println("inside " + this.getClass().getName());
}
}
Main.java
package com.oracle.javatests;
import com.oracle.javatests.ClassA.*;
// import com.oracle.javatests.ClassA.NestedAA.*; // Adding this will resolve NestedAB
public class Main {
public static void main (String[] args){
ClassA objA = new ClassA();
objA.printSomething();
NestedAA nestedAA = new NestedAA(); // Ok
NestedAB nestedAB = new NestedAB(); // Compiler error- NestedAB cannot be resolved to a type
}
}
The import statement does not import NestedAB type when using wildcards. A perhaps similar question led me to the java spec sheet which clarifies Type-Import-on-Demand Declarations :
A type-import-on-demand declaration allows all accessible types of a
named package or type to be imported as needed.
The accepted answer to the question implies that the on demand import declarations are not recursive. The reasoning is perhaps what Java considers "all accessible types of a named type", and the general concept of packages but I am falling short of connecting the dots and understand what accessible types means with respect to nested classes.
Can please anyone help explain how the type import and accessibility seem to work in java (while ignoring the arguable use of wildcard imports)
It's not heard to understand. import static com.foo.bar.*; is the exact same thing as import static com.foo.bar.[everything you can imagine here but without dots].
In other words, in your example, with import static pkg.ClassA.*; you can just write NestedAA without qualifiers and that works, because import static pkg.ClassA.NestedAA; would have made that work just the same.
You cannot write NestedAB unqualified and expect that to work; there is nothing you could possibly write instead of a * (which doesn't include dots) that would make that work, therefore, a star import doesn't make it work either.

Java : The import collides with another import statement

I have imported an Existing Java Application into my Workspace .
I see that , a class with same name is present in different packages with in the Application.
For example a class named "Status.java" is present with in
com.tata.model.common.Status;
com.bayer.frontlayer.dao.Status;
When I tried to use both of them within a class, for example as shown below
import com.tata.model.common.Status;
import com.bayer.frontlayer.dao.Status;
public class Adapter
{
}
It started giving an error in Eclipse stating
The import com.bayer.frontlayer.dao.Status collides with another import statement
Is there anyway to solve this without changing the name of the classes??
Thank you.
You can use them explicitly without importing them, so the included package name differentiates between the two:
//No imports required!
public class Adapter
{
private com.tata.model.common.Status x;
private com.bayer.frontlayer.dao.Status y;
}
You can import just one of the classes and use the fully qualified name for the other one.
e.g.
import com.tata.model.common.Status;
//import com.bayer.frontlayer.dao.Status;
class SomeClass{
void someMethod(){
new Status(); // com.tata.model.common.Status
new com.bayer.frontlayer.dao.Status(); //com.bayer.frontlayer.dao.Status
}
}
Though I think it would be less confusing in your case if you just used the fully-qualified names for both classes.
Directly apply full Class Names wherever applicable. Eg-
public class SomeClass {
public someMethod() {
com.myapp.someotherpackage.Status = "something";
com.some.other.package.Status = "otherthing";
if(com.myapp.someotherpackage.Status == com.some.other.package.Status) {
}
....
}
}

How to mock object with constructor that takes a Class?

This is the test:
import static junit.framework.Assert.assertTrue;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest( {ClassUnderTesting.class} )
public class ClassUnderTestingTest {
#Test
public void shouldInitializeMocks() throws Exception {
CollaboratorToBeMocked mockedCollaborator = mock(CollaboratorToBeMocked.class);
suppress(constructor(CollaboratorToBeMocked.class, InjectedIntoCollaborator.class));
whenNew(CollaboratorToBeMocked.class)
.withArguments(InjectedAsTypeIntoCollaborator.class)
.thenReturn(mockedCollaborator);
new ClassUnderTesting().methodUnderTesting();
assertTrue(true);
}
}
These are the classes :
public class ClassUnderTesting {
public void methodUnderTesting() {
new CollaboratorToBeMocked(InjectedAsTypeIntoCollaborator.class);
}
}
public class CollaboratorToBeMocked {
public CollaboratorToBeMocked(Class<InjectedAsTypeIntoCollaborator> clazz) {
}
public CollaboratorToBeMocked(InjectedIntoCollaborator someCollaborator) {
}
public CollaboratorToBeMocked() {
}
}
public class InjectedAsTypeIntoCollaborator {
}
public class InjectedIntoCollaborator {
}
This is the error :
org.powermock.reflect.exceptions.TooManyConstructorsFoundException: Several matching constructors found, please specify the argument parameter types so that PowerMock can determine which method you're refering to.
Matching constructors in class CollaboratorToBeMocked were:
CollaboratorToBeMocked( InjectedIntoCollaborator.class )
CollaboratorToBeMocked( java.lang.Class.class )
Here comes the question: how can I make PowerMock figure out what constructor to look for?
The problematic line is the suppress. That is where the error comes from.
Perhaps it is too late for your question. I met it today and found the solution at the following url. Basically, you need to specify your argument type like.
whenNew(MimeMessage.class).**withParameterTypes(MyParameterType.class)**.withArguments(isA(MyParameter.class)).thenReturn(mimeMessageMock);
http://groups.google.com/group/powermock/msg/347f6ef1fb34d946?pli=1
Hope it can help you. :)
I didn't know of PowerMock until you wrote your question, but did some reading and found this in their documentation. Still I am not really sure if that helps you:
If the super class have several
constructors it's possible to tell
PowerMock to only suppress a specific
one. Let's say you have a class called
ClassWithSeveralConstructors that has
one constructor that takes a String
and another constructor that takes an
int as an argument and you only want
to suppress the String constructor.
You can do this using the
suppress(constructor(ClassWithSeveralConstructors.class, String.class));
method.
found at http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior
Isn't it the thing you wanted?
EDIT: Now I see, you've already tried suppressing. But are you sure you got the suppress call right? Isn't the first argument of constructor() supposed to be the class you would like to surpress the constructor in?
If using PowerMock for EasyMock you can do PowerMock.expectNew(CollaboratorToBeMocked.class, new Class[]{InjectedIntoCollaborator.class}, ...) where the Class[] is the parameter types of the constructor you're expecting to be called. This will resolve the ambiguity between the constructors.

Same class name in different packages

Can same class exist in multiple packages?
In other words, can I have Foo.java class in com.test.package1 and com.test.package2?
Update
Now I copied class from package 1 and placed in to package 2 and now I am creating an instance of that class, I want this instance to point to class present in package 1 but currently it points to package1 path, how can i modify it?
Oh so I cannot do something like:
Foo = new Foo() // pointing to Foo class in package 1
Foo = new Foo() // pointing to Foo class in package 2
Yes, you can have two classes with the same name in multiple packages. However, you can't import both classes in the same file using two import statements. You'll have to fully qualify one of the class names if you really need to reference both of them.
Example: Suppose you have
pkg1/SomeClass.java
package pkg1;
public class SomeClass {
}
pkg2/SomeClass.java
package pkg2;
public class SomeClass {
}
and Main.java
import pkg1.SomeClass; // This will...
import pkg2.SomeClass; // ...fail
public class Main {
public static void main(String args[]) {
new SomeClass();
}
}
If you try to compile, you'll get:
$ javac Main.java
Main.java:2: pkg1.SomeClass is already defined in a single-type import
import pkg2.SomeClass;
^
1 error
This however does compile:
import pkg1.SomeClass;
public class Main {
public static void main(String args[]) {
new SomeClass();
new pkg2.SomeClass(); // <-- not imported.
}
}
Sure can but you'll need to distinguish which one you want when calling them in other packages if both are included within a source file.
Response to Comment:
com.test.package1.Foo myFoo = new com.test.package1.Foo();
com.test.package2.Foo myOtherFoo = new com.test.package2.Foo();
i was taken to this page by google when i had the error a type with the same simple name is already defined by the single-type-import. i fixed this error (AFTER A VERY LONG TIME) by realising the line import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; had snuck into the very top of my imports whilst i had the line import org.apache.commons.codec.binary.Base64; at the bottom of my imports.
So I was looking for a smarter solution than just using fully qualified names on one or both of the implemented classes.
If you create a private class, and extend your class, you are free to use the class, without writing the full package name each time.
Package 1
namespace namespace1.Logger
{
public class Log
{
public void Foo1(){}
}
}
Package 2
namespace namespace2.Logger
{
public class Log
{
public void Foo2(){}
}
}
My class implementation
//using namespace1.Logger;
//using namespace2.Logger;
namespace MyProject
{
public class MyClass
{
public MyClass()
{
LoggerA a = new LoggerA();
LoggerB b = new LoggerB();
a.Foo1();
b.Foo2();
}
private class LoggerA : namespace1.Logger.Log { }
private class LoggerB : namespace2.Logger.Log { }
}
}

Categories