JDK-6219964 : Compiler allows illegal cast of anonymous inner class
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-01-21
  • Updated: 2016-07-07
  • Resolved: 2005-09-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b55Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
The following source code compiles although it should be rejected because the anonymous inner class doesn't implement the interface Test231i and therefore it is illegal to cast the this pointer of the anonymous inner class to the interface:

class Test231 implements Test231i
{
	void	foo()
	{
		new Object()
		{
			Test231i	bar()
			{
				return	(Test231i)this;
			}
		};
	}
}


interface Test231i
{
}

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile  the example given in the description with javac.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compilation should fail with an error message.
ACTUAL -
No errors are reported by javac.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
class Test231 implements Test231i
{
	void	foo()
	{
		new Object()
		{
			Test231i	bar()
			{
				return	(Test231i)this;
			}
		};
	}
}


interface Test231i
{
}
---------- END SOURCE ----------
###@###.### 2005-1-21 06:52:01 GMT

Comments
WORK AROUND The cast will always fail at run time. The programmer almost certainly meant: return (Test231i)Test231.this;
26-09-2005

SUGGESTED FIX Index: src/share/classes/com/sun/tools/javac/comp/Check.java ============================================================ @@ -597,9 +597,13 @@ case TYP: if (sym.isLocal()) { mask = LocalClassFlags; + if (sym.name.len == 0) { // Anonymous class // Anonymous classes in static methods are themselves static; // that's why we admit STATIC here. - if (sym.name.len == 0) mask |= STATIC; + mask |= STATIC; + // JLS: Anonymous classes are final. + implicit |= FINAL; + } if ((sym.owner.flags_field & STATIC) == 0 && (flags & ENUM) != 0) log.error(pos, "enums.must.be.static"); ###@###.### 2005-1-21 19:58:58 GMT
21-01-2005

EVALUATION The submitter is correct. Quoting the JLS: 15.9.5 Anonymous Class Declarations: ... "An anonymous class is always implicitly final (8.1.1.2)." 5.5 Casting Conversion ... "compile-time reference type S (source) to a compile-time reference type T (target)." ... ... "If T is an interface type" ... "If S is a final class (8.1.1), then S must implement T, or a compile-time error occurs." The problem appears to be that the compiler don't mark anonymous classes final. ###@###.### 2005-1-21 09:21:15 GMT We should fix this in mustang. No apparent need for backport to JDK 5. ###@###.### 2005-1-21 20:05:33 GMT
21-01-2005