Kendall Ponder wrote:
So again, when is the instance variable first made available to use? Thanks!
So again, when is the instance variable first made available to use? Thanks!
8.3.2.3 Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
• The usage occurs in an instance (respectively static) variable initializer of C or
in an instance (respectively static) initializer of C.
• The usage is not on the left hand side of an assignment.
• The usage is via a simple name.
• C is the innermost class or interface enclosing the usage.
It is a compile-time error if any of the four requirements above are not met.
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Kendall Ponder wrote:According to K&B an init block runs right after the super() call in the constructor. My question is when are instance variables created. In the following code the compiler doesn't complain about the {y=8;} init code coming before y is declared which seems to mean the y instance variable is created before the init code is run.
Guillermo Ishi wrote:The decompiled code shows it's more like the constructor finishes last rather than begins last. And things within the constructor in the source get executed last. So the perception of when the constructor runs depends on point of view - source view or bytecode/reality view. Correct?
Oracle's Java Tutorial wrote:The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
Guillermo Ishi wrote:Last thing - I'm surprised the .class file doesn't show the call to super();
Paul Anilprem wrote:
JLS section 8.3.2.3 makes it very clear:
8.3.2.3 Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
• The usage occurs in an instance (respectively static) variable initializer of C or
in an instance (respectively static) initializer of C.
• The usage is not on the left hand side of an assignment.
• The usage is via a simple name.
• C is the innermost class or interface enclosing the usage.
It is a compile-time error if any of the four requirements above are not met.
Ashwin Rao wrote:I'm afraid I found it quite confusing. Could you please explain it in simpler terms? :\
Roel De Nijs wrote:
Ashwin Rao wrote:I'm afraid I found it quite confusing. Could you please explain it in simpler terms? :\
Don't worry! The JLS is sometimes very confusing, even for an experienced java developer like me. That's why I don't recommend reading this document when preparing for the OCAJP exam. It will add more confusion than it will clear your doubts.
Ashwin Rao wrote:I'm afraid I found it quite confusing. Could you please explain it in simpler terms? :\
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Ashwin Rao wrote:Firstly,In the JLS they've used a term called "respectively static" what does it mean?
Secondly,In the JLS in the first bullet point, does instance variable inititalizer mean an initializer block and what does instance initializer mean?
Thirdly,Usage via a simple name means directly using the variable (by only using variable name like y) from inside the class?
Thanks!
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Paul Anilprem wrote:
Ashwin Rao wrote:Firstly,In the JLS they've used a term called "respectively static" what does it mean?
It means the same concept applies to static member as well.
Paul Anilprem wrote:...no post explains why the second code n my previous post doesn't compile except the quote from JLS. It is true that JLS gets a little terse but confusing it is certainly not. One cannot get more precise and complete explanation than from JLS.
Can you tell me which sentence of the quote do you have trouble understanding?
Junilu Lacar wrote:
Paul Anilprem wrote:...no post explains why the second code n my previous post doesn't compile except the quote from JLS. It is true that JLS gets a little terse but confusing it is certainly not. One cannot get more precise and complete explanation than from JLS.
I'm yer huckleberry...
Can you tell me which sentence of the quote do you have trouble understanding?
The whole section you quoted has some pretty twisty logic and, judging from the difficulty folks are having understanding it, I would also respectfully disagree with your assertion that it's very clear and that it's not confusing. Honestly, I do find it confusing.
Let's take a look at it again:
8.3.2.3 Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C. The usage is not on the left hand side of an assignment. The usage is via a simple name. C is the innermost class or interface enclosing the usage.
It is a compile-time error if any of the four requirements above are not met.
Now let's look at your code that produces a compile-time error (Cannot reference a field before it is declared):
According to the JLS, you will get a compile-time error if any of the four requirements are not met. In other words, all four conditions must be true in order for the code to compile without error:
1. Check - usage of y on line 3 is inside an instance initializer
2. Check - usage of y on line 3 is not on the left hand side of an assignment
3. Check - usage is via a simple name; y is a simple name (vs a qualified name, a name consisting of a series of identifiers separated by "." tokens)
4. Check - TestClass is the innermost class enclosing the usage.
But wait, if all these conditions hold, why do we still get and, in fact, expect a compile-time error?
Now here's the twisty logic: If you look at the lead-in statement, it says "The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field..." Therefore, if all the conditions hold, then the lead-in condition that "the declaration of a member needs to appear textually before it is used" is enforced by the compiler. There's the answer: we get a compiler error because the condition in the lead-in statement has been violated, not because one of the four dependent conditions given did not hold.
If I were to hazard a guess, I would think whoever wrote this was a lawyer or something -- no offense to any who might be reading this. I think a normal person who isn't already very familiar with the JLS and how this particular thing works really has to sit there and work through that logic to see how it applies to the code sample you gave, Paul. I know I did. (But then again, I've been told that I'm not normal before, too )
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Paul Anilprem wrote:
The usage is not on the left hand side of an assignment.
2. Check - usage of y on line 3 is not on the left hand side of an assignment
... I interpreted the second condition "The usage is not on the left hand side of an assignment." more liberally and considered that passing a variable to a method belongs to the same category (because you are assigning the variable's value to the method parameter). My understanding is that the code doesn't compile because it violates this condition.
Junilu Lacar wrote:
Paul Anilprem wrote:
The usage is not on the left hand side of an assignment.
2. Check - usage of y on line 3 is not on the left hand side of an assignment
... I interpreted the second condition "The usage is not on the left hand side of an assignment." more liberally and considered that passing a variable to a method belongs to the same category (because you are assigning the variable's value to the method parameter). My understanding is that the code doesn't compile because it violates this condition.
Ah, but herein lies the rub: the JLS says "the usage is not on the left hand side" - the usage of y here, if you interpret it loosely as an assignment of a value to the method parameter, would be methodParameter = y, so the condition would still be satisfied because y is on the right hand side, not on the left hand side of that assignment. See, even in your interpretation the JLS got you confused.
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Junilu Lacar wrote:But I don't see the "only if" part of the lead-in statement as being irrelevant. Anyway, this just proves the point that the JLS can be a source of confusion and what it really says is up for interpretation, of which we've seen there can be a few conflicting ones. At any rate, I think my logic and analysis are sound and that the problem is with the condition specified in the lead-in statement, not that y was passed as a parameter to a method. If the JLS authors are so precise and unambiguous, why would they not explicitly cite that as a condition and leave it up for "loose interpretations"?
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Paul Anilprem wrote:Nobody is perfect... You still haven't shown any evidence to the contrary
Guillermo Ishi wrote:The simple name bullet might be messed up too, since this compiles fine.
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
The usage is not on the left hand side of an assignment.
The usage is via a simple name.
C is the innermost class or interface enclosing the usage.
Secondly,In the JLS in the first bullet point, does instance variable inititalizer mean an initializer block and what does instance initializer mean?
Yes, same as mentioned in the posts above.
Guillermo Ishi wrote:The simple name bullet might be messed up too, since this compiles fine.
Roel De Nijs wrote:
Kendall Ponder wrote:According to K&B an init block runs right after the super() call in the constructor. My question is when are instance variables created. In the following code the compiler doesn't complain about the {y=8;} init code coming before y is declared which seems to mean the y instance variable is created before the init code is run.
And now it's up to you to test your knowledge What's the output of this little program?
Hope it helps!
Kind regards,
Roel
Henry Wong wrote:
Kendall Ponder wrote:
So again, when is the instance variable first made available to use? Thanks!
Instance variables, that are not compile time constants, may be used right from the very beginning. And prior to being initialized, either by a constructor, instance initializer, etc., it has a default value, which for ints, that value is zero.
Henry
Junilu Lacar wrote:
Paul Anilprem wrote:Nobody is perfect... You still haven't shown any evidence to the contrary
I believe I (and inadvertently/unwittingly, you) have.
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Kendall Ponder wrote:
Secondly,In the JLS in the first bullet point, does instance variable inititalizer mean an initializer block and what does instance initializer mean?
Yes, same as mentioned in the posts above.
Paul, I don't think you answered the second part of the question (I had the same question). What is the difference between an instance variable initializer and an instance initializer? Thanks!
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Kendall Ponder wrote:I thought it meant the member only had to be declared first if all of the conditions were met.
...
Do I have this backwards?
Kendall Ponder wrote:
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
I'm either not following the conversation between Paul and Junilu or else I'm not following the JLS. What does appearing textually before it is used mean? I thought it meant the member only had to be declared first if all of the conditions were met. It appears Paul and Junilu are interpreting it to mean the exact opposite. When I applied my interpretation to Paul's two snippets.
Snippet A
Snippet B
The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
The usage is not on the left hand side of an assignment.
The usage is via a simple name.
C is the innermost class or interface enclosing the usage.
In snippet A the usage of y is on the left side of an assignment so all four conditions are not met (to be met the useage must not be on the left side) so the y=8; can appear before the int y=10; in the code. In snippet B all four conditions are met so the System.out.println(y); must appear after the int y=10; and since it does not you get a compiler error. Do I have this backwards?
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Kendall Ponder wrote:
Secondly,In the JLS in the first bullet point, does instance variable inititalizer mean an initializer block and what does instance initializer mean?
Yes, same as mentioned in the posts above.
Paul, I don't think you answered the second part of the question (I had the same question). What is the difference between an instance variable initializer and an instance initializer? Thanks!
Paul Anilprem wrote:
You got it. Im interpreting it the same way. Im not sure what is Junilu's interpretation.
Kendall Ponder wrote:
Snippet B
...
The usage is not on the left hand side of an assignment.
...
In snippet B all four conditions are met so the System.out.println(y); must appear after the int y=10; and since it does not you get a compiler error. Do I have this backwards?
I interpreted the second condition "The usage is not on the left hand side of an assignment." more liberally and considered that passing a variable to a method belongs to the same category (because you are assigning the variable's value to the method parameter). My understanding is that the code doesn't compile because it violates this condition"
Roel De Nijs wrote:
Kendall Ponder wrote:
Secondly,In the JLS in the first bullet point, does instance variable inititalizer mean an initializer block and what does instance initializer mean?
Yes, same as mentioned in the posts above.
Paul, I don't think you answered the second part of the question (I had the same question). What is the difference between an instance variable initializer and an instance initializer? Thanks!
The instance initializer has its own section in the JLS So that's what we know as an instance initializer block (or an init block). Like this:
The instance variable initializer is like its name suggest: an initializer for an instance variableThe right-hand side of the equals sign in an initializer can be any expression that evaluates to the type of the instance variable.
Consider Paul's rocket mass heater. |