Why should I use the keyword "this" for direct links?

When I use the this to access a non-static variable in a class, Java gives no errors. But when I do not use it, Java gives an error. Why should I use this ?

I know when I usually use this , but this example is very different from ordinary customs.

Example:

 class Foo { // int a = b; // gives error. why ? int a = this.b; // no error. why ? int b; int c = b; int var1 = this.var2; // very interesting int var2 = this.var1; // very interesting } 
+55
java this class
Oct 27 '17 at 4:54 on
source share
5 answers

Variables are declared first and then assigned. This class is the same:

 class Foo { int a; int b; int c = b; int var1; int var2; public Foo() { a = b; var1 = var2; var2 = var1; } } 

The reason you cannot do int a = b; , is that b is not yet defined at the time the object was created, but the object itself (i.e. this ) exists with all its member variables.

Here is a description for each:

  int a = b; // Error: b has not been defined yet int a = this.b; // No error: 'this' has been defined ('this' is always defined in a class) int b; int c = b; // No error: b has been defined on the line before 
+45
Oct 27 '17 at 5:35 on
source share

For a full description , see Section 8.3.3 Java Language Specifications: " Direct Links During Field Initialization "

A direct reference (referring to a variable that has not yet been declared at this point) is only an error if everything is correct:

  • An instance variable declaration in a class or C interface appears after using an instance variable text

  • Usage is a simple name in a C instance variable initializer or C instance initializer;

  • Use is not on the left side of the assignment;

  • C is the innermost class or interface that spans usage.

See bold text: "use is a simple name." A simple name is the name of a variable without further qualification. In your code, b is a simple name, but this.b is not.

But why?

The reason is because the italic text in the example in JLS reads:

"The limitations given above are intended to catch at compile time, circular or otherwise distorted initializations."

In other words, they allow this.b because they believe that a qualified link makes it more likely that you carefully thought about what you are doing, but just using b probably means you made a mistake.

This is the rationale for Java designers. As far as this is true in practice, as far as I know, I have never been investigated.

Initialization order

To expand on above, citing Dukeling's comment on the issue, using the qualified this.b link this.b most likely not give you the desired results.

I limit this discussion to instance variables because the OP refers only to them. The order in which instance variables are assigned is described in JLS 12.5 Creating Instances of a New Class . It must be taken into account that the superclass constructors are created first, and the initialization code (assignments and initialization blocks) is executed in textual order.

So, given

 int a = this.b; int b = 2; 

as a result, we get a equal to zero (the value of b at the time of execution of a initializer) and b is 2.

Even stranger results can be achieved if the superclass constructor calls a method that is overridden in a subclass, and this method assigns the value b .

So, in general, it is recommended to think about the compiler and either change the order of your fields, or fix the main problem in the case of cyclic initializations.

If you need to use this.b to get around the compiler error, then you are probably writing code that will be very difficult for the person to maintain after you.

+69
Oct 27 '17 at 5:43 on
source share

You presented 3 cases:

  • int a = b; int b;
    This gives an error, because the compiler will look for b in memory, and it will not be there. but when you use the this , it explicitly indicates that b defined in the scope of the class, all class references will look for it, and finally it will find it.
  • The second scenario is quite simple, and, as I described, b is defined in the region before c and will not be a problem when looking for b in memory.
  • int var1 = this.var2;
    int var2 = this.var1;
    In this case, there is no error, because in each case the variable is defined in the class, and the destination uses this , which will look for the assigned variable in the class, and not just the context that follows.
+4
Oct 27 '17 at 6:16
source share

For any class in Java, this uses a default reference variable (unless a specific reference is specified) that any user can provide, or the compiler will provide inside a non-static block. for example

 public class ThisKeywordForwardReference { public ThisKeywordForwardReference() { super(); System.out.println(b); } int a; int b; public ThisKeywordForwardReference(int a, int b) { super(); this.a = a; this.b = b; } } 

You said that int a = b; // gives error. why ? int a = b; // gives error. why ? gives a compile-time error because b declared after a , which is an Illegal Forward Reference in Java and is considered a compile-time error.

But in the case of methods Forward Reference becomes legal

 int a = test(); int b; int test() { return 0; } 

But in my code, a constructor with an argument is declared before a and b , but it does not give any compile-time error, because System.out.println(b); will be replaced by System.out.println(this.b); the compiler.

The this simply means the current reference to the class or reference that the method, constructor, or attribute is accessing.

 A a1 = new A(); // Here this is nothing but a1 a1.test(); // Here this is again a1 

When we say a = this.b; , he indicates that b is an attribute of the current class, but when we say a = b; , since it is not inside the non-static this block, it will not be present and will look for an attribute declared earlier that does not exist.

+4
Oct 27 '17 at 6:22
source share

Please check out the Java Language Specification: https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3

This is the reason IMO: The usage is via a simple name.

So, in this case you need to specify a name using this .

+3
Oct 27 '17 at 5:38 on
source share



All Articles