Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 438890

Summary: Can access class member when defining anonymous object in a static method
Product: [Eclipse Project] JDT Reporter: Georgi Pachov <georgi.patchov>
Component: CoreAssignee: Sasikanth Bharadwaj <sasikanth.bharadwaj>
Status: CLOSED WONTFIX QA Contact:
Severity: minor    
Priority: P3 CC: awang060843, georgi.patchov, srikanth_sankaran
Version: 4.3.2   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard: stalebug

Description Georgi Pachov CLA 2014-07-03 20:23:49 EDT
Steps to reproduce:
Create a top-level class, for example *Main*.
Create a privtate *final* member and assign it, for example:
private final int c = 3;

Create a static method, in the body of which you create a new anonymous object(let's say a runnable).
In the body of the run method, *I am able to use Main.this.c* and print it out to the console. c is not static.

Eclipse compiles it and runs it and prints out the value of c. 
In comparison, the code does not compile using javac (JDK-7).

See/paste the code below:

public class Main {
    private final int value = 3;

    public static Runnable buildRunner() {
        return new Runnable() {

            @Override
            public void run() {
                System.out.println(Main.this.value);
            }
        };

    }
}

In eclipse it compiles and runs, in javac it reports a compile-time error.

Also, see http://stackoverflow.com/questions/24564763/why-am-i-able-to-print-this-field-in-a-static-method/24564845#24564763 for more details.
Comment 1 Srikanth Sankaran CLA 2014-07-21 02:04:54 EDT
Sasi, please check the earliest version with this problem. OIOW, is this a recent
regression ?
Comment 2 Sasikanth Bharadwaj CLA 2014-07-21 04:34:23 EDT
Very old problem, introduced in 3.2 by the commit http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=c84496f37e5dff715764911530c1fceaa60b14ee

In QualifiedThisReference.resolveType(), we see this

// Ensure one cannot write code like: B() { super(B.this); }
if (depth == 0) {
	checkAccess(scope, null);
} // if depth>0, path emulation will diagnose bad scenarii

but the path emulation happens only in QTR.generateCode() which is skipped in FieldReference to generate optimized field access as per bug 117451
so in effect, the validation for above piece of code does not occur at all

Another consequence of not calling path emulation until generateCode() is that similar errors do not get reported at all if there are other type errors in the code

for example, in the code below,

public class Main {
    private final int value = 3;
    public int getValue() {
    	return 0;
    }
    public static Runnable buildRunner() {
        return new Runnable() {
            @Override
            public void run() {
                Main.this.getValue();
            	//s = "asdsd";
            }
        };

    }
}

the access to getValue() is marked as an error, but if the line following that is uncommented, the error on the previous line is no longer reported
Comment 3 Eclipse Genie CLA 2020-02-16 09:12:28 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.