开发者

Question about class members in Java

If I have a class SOmeClass, with a method someMethod, in the following code how does the compiler read the class member someConstant?

Class SomeClass{
            private int someConstant = someMethod(3); //3 is arbitrary

            private int anotherConstant;
            SomeClass(){
                 //constructor
                 anotherConstant = someConstant;
                     }

            public int someMethod(int an_int_value){
                 //something
      开发者_高级运维              return new_int;
                      }

This question is about my confusion of how compilers work. ANd how the machine reads code. The constant someConstant cannot be initiated until the class is instantiate, because the compiler needs to know what the method someMethod does. But the contructor can't be completed because anotherCOnstant needs to have this unknown value too. It seems to me (someone with no experience of computer science) that this is a catch-22 situation. This question is not limited to Java. It's just my most familiar language.


Object instantiation in Java is a multistep process. First, every field in the class is initialized to its default value (0, false, or null as appropriate). Next, each field with an initializer is, in order, initialized to this value. If this means calling any methods, then those methods are invoked with the fields either holding their default (if they haven't been touched yet) or the value they've been initialized to. Finally, the constructor is invoked.

Notice that this means that the memory for the object is allocated before the constructor runs. This is necessary in order for this approach to work.


You seem to be confusing the compiler with the run time. What the someMethod() does is determined at compile time and stored in the .class file that is output. The run time reads in these .class files and builds Class definitions from them. So it has a complete knowledge of what someMethod() does before you ever try to instantiate a SomeClass. There is no restriction that the constructor needs to have finished running before methods of the class have a definition.

What java does is run all of the initializers in the order they're declared, then start what's in the actual constructor. Consider:

private Integer foo = getFoo();
private Integer bar = Integer.valueOf(4);
private Integer getFoo() {return bar;}

foo will be null when we're done, because it was declared first and bar was still null when we assigned it.

private Integer bar = Integer.valueOf(4);
private Integer foo = getFoo();
private Integer getFoo() {return bar;}

This way foo will be 4 when construction is done! Either way, the runtime can look up the definition of the getFoo() method before the constructor is done, because the compiler put a definition of it in the class file.


Not being an expert on the Java VM, I'll still try to answer your question:

  1. Your problem is actually not one that concerns the compiler - the compiler only turns your readable Java code into binary instructions. The problem of having uninitialized variables would occur at runtime, unless the compiler was "smart" enough to find circular dependencies in your code.

  2. None of your values are constants - they would have to be declared final, and you would not be able to set anotherConstant like that if you had it declared that way. They are both variables.

  3. At first, your class will be loaded into memory. So the basic memory layout of SomeClass will be known, and so will the functionality of someMethod(). If you had static variables declared, they would also be initialized now, but you couldn't call an instance method like someMethod to do so.

  4. When you instantiate an object of type SomeClass, all the member variables will be set first, so someConstant will no longer be unknown. Since the functionality of someMethod is also known, this should not be a problem. Were you referring to an undeclared variable at some point in someMethod, a NullPointerException would be thrown.

  5. Finally, the constructor is called. At this point, all the member variables are available, so it all will run smoothly. Again - were there any undeclared variables, a NullPointerException would be thrown. In your example, there should not be any, though.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜