Search code examples
javaimportclassname

In Java, can imported class have same simple-name as importing class? Are there any restrictions?


If I have a class names ClassX in package a.b.c, and I want to import the class a.b.x.ClassX

Is there some restriction in Java preventing me from doing so? As far as usage goes, I can always use the fully qualified name of the imported class, right?

Eclipse seems to be unable to resolve this import, I need to know if there is a restriction in Java itself that is causing the problem.

Is the following code legal:

a\b\c\ClassX.java :

package a.b.c;
public class ClassX {
//
}

a\b\x\ClassX.java :

package a.b.x;

import a.b.c.ClassX;

public class ClassX {
    public static void main(String[] args) {
        a.b.c.ClassX newObj = new a.b.c.ClassX();
    }
}

If no, then why?


Solution

  • To be more precise

    • it is NOT that we are not allowed to import classes with same simple name as class importing it,
    • but we are not allowed to name importing class same as any class which is already imported.

    Attempting to do so will result in error message: [NameOfImportingClass] is already defined in this compilation unit.

    Purpose of this restriction is to prevent name ambiguity/clashes.

    For example without imports all below is legal:

    package a;
    class B{}
    
    package b;
    class B{
       a.B objectPackageaB; //legal - full-package-name so no ambiguity
       b.B objectPackagebB; //legal - full-package-name so no ambiguity
       B objectB; //legal, as now it can only represent B from package "b" -> b.B 
    }
    

    Now lets add import a.B

    package b;    
    import a.B; // <---
    
    class B {
         b.B objectbB;  //still legal, full-package-name so no ambiguity
         a.B objectaB;  //still legal, full-package-name so no ambiguity
         B objectB;   //ambiguous, so ILLEGAL. Which type B should represent? a.B OR b.B?
    }
    

    IF Java would not prevent such situation, it would need to make decision what type B objectB should represent.

    We have two options:

    1. it would represent b.B so type which is importing. But that means to use B from a package we still would need to write it as a.B, which means import a.B; is redundant/dead code which would only be confusing programmers.
    2. it would represent a.B so type which is imported. But that would feel unnatural since inside class B{ }, B would represent some other type!.

    Neither of above solutions are good.

    If there is no good solution to a problem, best option is to prevent from appearing.