0

in documentation i read, that:

A variables name can be any legal identifier — an **unlimited-length** sequence of Unicode letters and digits

so, i created this class:

class Test{
public static void main(String args[])
{
int i=10;
}}

where i - its not i, its variable with name length - 3000000 chars. the size .java file ~3M.

I try compile this file:

javac Test.java

In result i have Test.class with size Test.class 4bayts.

And now my questions:

  1. Its really try, that name unlimited-length??
  2. How compiler translate my variable name with length 3000000 chars, that in result i have so small .class file?
user471011
  • 7,104
  • 17
  • 69
  • 97

4 Answers4

5

iiiiiii.. is a local variable, i.e. it cannot be accessed from other classes. Therefore, its name does not matter; the compiler does not need to store it. Additionally, the compiler may look at your code and determine that {int i = 10;} is not actually doing anything and can be replaced by {} since both versions produce the same program output (none).

phihag
  • 278,196
  • 72
  • 453
  • 469
  • no, decompiler result: public class Test { public static void main(String[] var0) { boolean var1 = true; } } – user471011 Dec 05 '10 at 16:26
  • @user471011 Sorry if I wasn't clear: The compiler *is allowed to* optimize like that: The specific compiler product and version you're using decided not to. – phihag Dec 05 '10 at 16:29
  • 1
    How can it be decompiled to a boolean with value true if your source has an int with value 10 !? – Goran Jovic Dec 05 '10 at 16:32
  • @user471011 compilers generally don't keep the `LocalVariableTable` by default anyway. – Bruno Dec 05 '10 at 16:32
  • 2
    Ok, I did try it, and I found some really interesting results! Try adding `System.out.println(i);` right after variable declaration, recompile and then decompile it again with this service. You'll see that it will be declared as `byte` because as far the compiler saw the largest value it is ever going to receive fits this type, so why waste more. Since, your first version didn't use it at all, compiler didn't even bother to set it to a number type and just defaulted it to boolean. – Goran Jovic Dec 05 '10 at 17:06
  • 2
    Which is for all practical purposes equal to the behavior described by phihag. – Goran Jovic Dec 05 '10 at 17:07
1

1) I wouldn't be surprised if some compiler implementations had (reasonable) limits while others could handle variable names of any length. Unfortunately, I don't know of any documented specific examples or have any specific experiences of either off-hand.

2) Local variables names don't have to be maintained in the class file (they aren't accessible via reflection). Try making a file with an instance variable name that long and see the resulting class file.

Bert F
  • 85,407
  • 12
  • 106
  • 123
1

The local variable names are not stored as such. They tend to be removed as part of the compiler optimization and replaced with numbers (see aload_<n> for example).

Try to compile with javac -g or javac -g:vars, it should leave more information, which you'll be able to check with javap.

This answer should have interesting details on this topic.

Since your example code doesn't actually do anything anyway, it's likely to be optimized into an empty method.

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
0

The compiler has probably changed your really long name to something boring like "a".

The variable name is there for the programmer's convenience. To the compiler and JVM it makes no difference if it's 1 character or 1 million as long as it's unique.

Ventral
  • 1,194
  • 9
  • 5
  • This won't always be true. For example, the compiler would never rename `public static` variables in libraries which are meant to be referenced by other packages. – Matt Dec 05 '10 at 16:20
  • @Matt, even private members tend not to be renamed, but the original question was about local variables as far as I understood it. – Bruno Dec 05 '10 at 16:24