Why must I use the “this” keyword for forward references?

When I use the this keyword for accessing a non-static variable in a class, Java doesn’t give any error. But when I don’t use it, Java gives an error. Why must I use this?

I know when should normally I use this, but this example is very different from normal usages.

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
}

5

The full description is in section 8.3.3 of the Java Language Specification: “Forward References During Field Initialization

A forward reference (referring to a variable that is not declared yet at that point) is only an error if the following are all true:

  • The declaration of an instance variable in a class or interface C appears textually after a use of the instance variable;

  • The use is a simple name in either an instance variable initializer of C or an instance initializer of C;

  • The use is not on the left hand side of an assignment;

  • C is the innermost class or interface enclosing the use.

See the bolded text: “the use is a simple name”. A simple name is a variable name without further qualification. In your code, b is a simple name, but this.b is not.

But why?

The reason is, as the cursive text in the example in the JLS states:

“The restrictions above are designed to catch, at compile time,
circular or otherwise malformed initializations. “

In other words, they allow this.b because they think that a qualified reference makes it more likely that you have thought carefully about what you’re doing, but simply using b probably means that you made a mistake.

That’s the rationale of the designers of the Java Language. Whether that is true in practice has, to my knowledge, never been researched.

Initialization order

To expand on the above, in reference to Dukeling’s comment on the question, using a qualified reference this.b will likely not give you the results you want.

I’m restricting this discussion to instance variables because the OP only referred to them.
The order in which the instance variables are assigned is described in JLS 12.5 Creation of New Class Instances.
You need to take into account that superclass constructors are invoked first, and that initializations code (assignments and initialization blocks) are executed in textual order.

So given

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

you will end up with a being zero (the value of b at the time that a‘s initializer was executed) and b being 2.

Even weirder results can be achieved if the superclass constructor invokes a method that is overridden in the subclass and that method assigns a value to b.

So, in general, it is a good idea to believe the compiler and either reorder your fields or to fix the underlying problem in case of circular initializations.

If you need to use this.b to get around the compiler error, then you’re probably writing code that will be very hard to maintain by the person after you.

2

Variables are declared first and then assigned. That class is the same as this:

class Foo {
    int a;
    int b;
    int c = b;

    int var1;
    int var2;

    public Foo() {
        a = b;

        var1 = var2;
        var2 = var1;
    }
}

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

Here’s 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  

2

You have presented 3 cases:

  1. int a = b;
    int b;

    This gives error because the compiler will look for b in the memory and it will not be there. but when you use this keyword then it specifies explicitly that the b is defined in the scope of the class, all class references will be looked up for it, and finally it will find it.
  2. Second scenario is pretty simple and as I described, b is defined in the scope before c and will not be a problem while looking for b in the memory.
  3. int var1 = this.var2;
    int var2 = this.var1;
    In this case no error because in each case the variable is defined in the class and assignment uses this which will look for the assigned variable in the class, not just the context it is followed by.

For any class in Java this is a default reference variable (when no specific reference is given) that either user can give 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 ? gives compile time error because b is declared after a which is an Illegal Forward Reference in Java and considered as 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, the constructor with the argument is declared before both a & b, but not giving any compile-time error, because System.out.println(b); will be replaced by System.out.println(this.b); by the compiler.

The keyword this simply means current class reference or the reference on which the method, constructor or the attribute is accessed.

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

When we say a = this.b; it is specifying that b is a current class attribute, but when we say a = b; since it is not inside a non-static block this won’t be present and will look for an attribute declared previously which is not present.

1

Please look at 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 have to specify the name using this.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật