Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java changing variable name changes program behaviour

I found a scenario where java program behaves differently after renaming a variable. I understand this isn't actually code that anyone would use but if someone knows whats going on it would be nice to have an explanation. I tried this with java 1.6 on Eclipse Kepler.

package _test;

public class TestClass{
    public static void main(String...args){
        Object testClazz$1 = new Object (){
            public String toString() {
                return "hello";
            }
        };
        TestClass$1 test = new TestClass$1();
        System.out.println(testClazz$1.toString());
        test.doStuff();
    }
}

class TestClass$1{
    public void doStuff(){
        System.out.println("hello2");
    }
}

This outputs:

hello

Exception in thread "main" java.lang.NoSuchMethodError: _test.TestClass$1.doStuff()V at _test.TestClass.main(TestClass.java:13)

As far as I understand the compiler creates a TestClass$1.class file for the testClazz$1 object and this causes a naming collision.

But after renaming the object to testClass$1:

package _test;

public class TestClass{
    public static void main(String...args){
        Object testClass$1 = new Object (){
            public String toString() {
                return "hello";
            }
        };

        TestClass$1 test = new TestClass$1();
        System.out.println(testClass$1.toString());
        test.doStuff();
    }
}

class TestClass$1{
    public void doStuff(){
        System.out.println("hello2");
    }
}

The output is:

_test.TestClass$1@2e6e1408

hello2

Any ideas what is going on here?

like image 631
user3139461 Avatar asked Jul 16 '14 14:07

user3139461


People also ask

Can you change the variable name Java?

No, a variable name can't be changed.

Can a variable name be changed?

You cannot rename variables in runtime.

How do you change a parameter name in Java?

Highlight and right click on the variable you want to rename. Navigate to Refactor and select Rename.... Type in your new variable name and press Enter.


1 Answers

Anonymous classes are named automatically by appending a $ sign and an increasing number to the name of the enclosing class.

In your first example the anoymous class will be named TestClass$1 which has no doStuff() method, you only override toString() that's why you get NoSuchMethodError error.

In your 2nd example you already have a local variable named TestClass$1, so the auto-generated name chosen by the compiler will be a different name, most likely TestClass$2. Since you instantiate TestClass$1 which is not an anonymous class but a class explicitly defined by you, that will be instantiated which has a doStuff() method which properly prints "hello2" and which does not override Object.toString() so printing the value returned by its toString() method will print the default value as specified in java.lang.Ojbect (which is the class name appended with a @ sign followed by the default hash code in hexadecimal format).

Conclusion: While this is an interesting example, you should never use the $ sign in your class names and in identifier names.

like image 65
icza Avatar answered Sep 17 '22 14:09

icza