-
Notifications
You must be signed in to change notification settings - Fork 693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify use of this
in initializing instance variables
#5310
Merged
Merged
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
4ff61a8
Update classes.md
pdhankhar61 e29e927
Merge branch 'main' into patch-2
MaryaBelanger c2e9376
review
MaryaBelanger a300e3f
fix excerpt file
MaryaBelanger 1c40517
Merge branch 'main' into patch-2
MaryaBelanger 1e05c93
fix code again
MaryaBelanger e495000
Apply suggestions from code review
MaryaBelanger c46257e
fix formatting
MaryaBelanger 40ec9bf
ignore example error in CI
ericwindmill ac2416c
ignore error in CI
ericwindmill 46ff8d5
refresh snippets
ericwindmill adc7bea
refresh snippets
ericwindmill 181cdd4
Merge branch 'patch-2' of https://github.com/pdhankhar61/site-www int…
ericwindmill a28b0d0
refresh snippets
ericwindmill 2de12d3
comments on separate lines to bypass inconsistent auto-formatting
MaryaBelanger d2689f2
remove ignores
MaryaBelanger 8ae0e42
Remove unnecessary region
parlough File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why you'd think that this doesn't initialize
i
:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Respected,
I am talking about non-late but final instance variable which is initialized at declaration time. In that case "this" keyword will not be accessible.
In this case "this.c" will show error. Because it is already initialized.
But if "c" is not final then you can reassign it a new value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but the paragraph you're referring to is about access to
this
in an initializing expression (which is the expressione
that may occur after=
in a variable declaration), and it is true for final as well as non-final variables that the initializing expression doesn't have access tothis
. (Also, the given explanation is valid for both kinds of variables.)It's a bit like seeing "You can't go faster than 25MPH here!" and suggesting that we should change it to "You can't go faster than 25MPH here on rainy days!". If the first sentence is true then the second one is true, too, but it isn't helpful to introduce a reduction of scope when the statement is true for the original, broader scope. It indirectly implies that the original statement wasn't true, but that's incorrect: It was true.
Same structure here: The fact that there is no access to
this
in an initializing expression is true for all non-late instance variables, not just for final ones.[Edit: added the word 'non-late' near the end.]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, @pdhankhar61 your issue is with the existing statement:
And you're saying that statement is incorrect because you tried accessing
this
for the non-late instance variablesa
,b
andc
, and it works:But you found that statement is true if the variable is
final
, so you're updating the statement to specifyfinal
?I could be totally missing the point of the section, but I'm finding it confusing too. It also doesn't seem like the example code starting on line 183 is related to the paragraph immediately preceding it (the same paragraph in question), which makes it even more confusing.
@eernstg (or anyone) So it's not just about initialization of non-late instance variables in general, but specifically that the paragraph makes it sound like you can't use
this
to initialize non-late instance variables -- why does it say that doesn't work?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is what it means that the initializing expression of a non-late instance variable does not have access to this:
At (1), we have the initializing expression
this.b
. We could have written a plainb
, because that's just a concise notation for the same thing. In both cases it is a compile-time error to have such an initializing expression, because "that location does not have access tothis
".The point is that the initializing expression
e
of a non-late instance variable is evaluated before the object under construction is complete, so we can't allow any user-written code (likee
) to see the object, yet.If the variable is
late
then it can also have an initializing expression, and in this case it does have access tothis
, because it's only evaluated later, when the object is complete. Solate double a = this.b;
is fine.However, the occurrence of
this
at (2) is completely different: That's a declaration of a formal parameter of the constructor namedPoint
, and this particular kind of parameter is known as an 'initializing formal'.The syntax of an initializing formal is roughly
<type>? 'this' '.' <identifier>
, and it works as follows: The type<type>
is usually omitted (the?
is there to indicate that we can omit it), so let's ignore that. It's an error if this declaration is a formal parameter of anything other than a non-redirecting generative constructor. The identifier must be the name of an instance variable of the enclosing class / mixin class / enum. Finally, at run time it causes the given instance variable to be initialized to the actual argument which is passed for that parameter.So
this.b
at (2) is not an expression, and it doesn't allow us to write any code that accesses the object at a point in time where it is incomplete, it's just a "magic word" which indicates that this formal parameter is an initializing formal. The constructor could also have been written asPoint(double b) : this.b = b;
, so the magic wordthis
is just a request for this particular kind of syntactic sugar. The syntaxthis.b = b
is in turn equally magic: The occurrence ofthis.b
is not a general expression, it's a special syntax that allows us to specify that this particular element in the initializer list is used to initialize the instance variable namedb
. (We could omitthis
again). The point is again that initialization of the state of the object must take place under very controlled circumstances, because we cannot let user-written code access the object before it is complete. That's what all those "not a general expression" incantations are about.In particular, 'access to
this
' has nothing to do with initializing formals, in spite of the fact that the latter usesthis
as part of the syntax.But it might be helpful to say, somewhere, that an initializing formal parameter isn't an "access to
this
" because it isn't an expression.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay Now, I have understood you point @eernstg sir. Like that statement was confusing without example. I think you should add the example for that statement.
Delay in response is because of github, because it sends notifications with a delay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @pdhankhar61!
So what have we learned here? Taking a look at the section as a whole, the following comes to mind:
I think it's confusing that this section says 'All uninitialized instance variables have the value
null
', and it does not even mention that for many instance variables (namely the ones whose declared type is potentially non-nullable) it is simply a compile-time error if they are left uninitialized.If we mention this then it also makes sense to mention the error, perhaps right after "can't access
this
":@MaryaBelanger, I understand that this kind of documentation should be extremely succinct and to the point, but what do you think about adding something like this?
We should probably also mention somewhere that an initializing formal isn't an expression and hence it isn't an "access to
this
" even in the case where it's written literally asthis.x
, but that might be better placed in a section where initializing formals are introduced (the same section does use one initializing formal, but only refers to it as 'a constructor parameter', so perhaps initializing formals aren't described here at all).