javaclass

In Java, the variable name can be same with the classname


In Java I can declare a variable, whose name is total same with its classname. I think it is a so confusing and strange design.

So I have a problem in the code snippet below: how can the compiler distinguish the ClassName, it is referenced the variable name or class name?

In the running result, the compiler references ClassName as a variable name.

class ClassName{}

public class Test {
    public static void main(String[] args){
        ClassName ClassName = new ClassName();
        System.out.println(ClassName); //ClassName@18fb53f6
    }
}

Solution

  • The compiler can tell by context. In the example you have given:

    ClassName ClassName = new ClassName();
        1         2               3
    

    It can see that 1 is where a type name should be, so it knows you mean the class. Then, 2 is where a variable name is expected, so it knows that this should be the name of a variable. And 3 is coming after the new keyword with parentheses, so it must be the name of a class.

    System.out.println( ClassName );
    

    In this instance, ClassName is in the context of argument passing. A type name can't be passed as an argument, so you must mean the name of the variable.

    To amuse yourself, you can change the print statement to:

    System.out.println( ClassName.class );
    

    Hover your mouse cursor on ClassName and you'll see that the compiler recognizes this as the name of a class. Then change it to:

    System.out.println( ClassName.getClass() );
    

    Hover your cursor again, and now you see that it recognizes it as the variable name. That's because .class can only be applied to a type name, while getClass() can only be applied to an object reference. The result of the print statement would be the same in both cases - but through different mechanisms.

    So the compiler has no problem here. But you are right that it's not readable to humans. The convention is that names of variables and methods must start with a lowercase letter, while type names must start with an uppercase letter. Adhering to this convention will ensure that no such readability problems arise.

    I can't say exactly why the authors of Java chose not to enforce this convention (that is, give a compiler error if type names started with a lowercase letter or variable/method names started with an uppercase), but I speculate that they didn't want to make anything an actual error unless it would actually cause an ambiguity for the compiler. Compilation errors are supposed to indicate a problem that makes the compiler unable to do its work.