Import implementation
First, I'm not a Java guy, but I ran into what appears to surface to be inconsistent with how imports work.
Let's say you have a file and in that file you have a main function and you also define a class Foo , now another implementation of Foo also exists in the package. Let's say you want to use both versions in your functionality.
You cannot explicitly import Foo from it, i.e. import mypackage.Foo;
How this would lead to a conflict with a class defined locally in the file, so an error is generated at compile time.
What you can do is import the whole package i.e. import mypackage. *;
This will work, and you can access Foo using the fully qualified name, using the simple name will result in using the local Foo . The inconsistency I see is that while the former generates an error (you imported the class and the only purpose of the import is to use a plain name, not a fully qualified name), the latter doesn't even generate a warning.
I would think both cases would generate a warning, i.e. you may be using the wrong class as it is defined in 2 places, or the import statement is redundant as using a simple name will be resolved to a locally defined class and not imported.
So my question is, is there a main reason why it is implemented this way?
Yes, this is a case of violation, I understand that.
a source to share
As stated above, imports effectively do nothing about a relation Foo
in another package; whether you import or not, you cannot refer to that other Foo through the short class name, and you can refer to it using the fully qualified class name.
Conceptually, you might think of import mypackage.*
not necessarily "import all classes from mypackage
", but perhaps "import all non-conflicting classes from mypackage
". I don't know how Sun's compiler implementation does it, but he can definitely decide not to map mypackage.Foo as part of the template (and thus not import it at all) and the code will work the same anyway.
Importing is just setting up an alias from the short class name to the fully qualified class name (like when I say Date
interpret this as java.util.Date
). You should expect to get a warning if you do something completely redundant, such as importing only the conflicting class. However, if you pull in the whole package from *
, it would be wrong for me if the compiler complained that one of the class collisions; it would be so common in practice, and innocuous 99% + of the time, that it gave rise to the boy who cried wolf syndrome to the point that you would hardly pay attention to these and other warnings as you just get used to to be bombarded.
By the way, if you import both java.util.*
and java.sql.*
, this is allowed and by itself does not result in any warnings; but if you try to refer to simply Date
(without such a class in your local package) you will get a compilation error as the name will be ambiguous.
a source to share
import mypackage. * may be required for all other stuff that is in mypackage. If there was a warning, it would be difficult to avoid it altogether, i.e. You would have to fully qualify all other classes, etc., that you use from mypackage. Worse, consider the case where version 1 of mypackage does not contain Foo, so there was no conflict and therefore no warning at all. Version 2 contains Foo, but of course it is not the Foo you want to access in your program. So if the compiler warns about "import package. *" Conflicts, It makes "import package. *" Potentially less upstream.
a source to share
You can think of "import p. *" As meaning "when you cannot resolve a name in the current file, try to resolve it in package p". The compiler does not import everything in p at the point where it sees the import statement. Instead, it looks in p (and other packages named in import ... * statements) when it finds a name that it cannot resolve in direct compilation.
a source to share