JDK-4351453 : `final' variables and inner classes
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 1.3.0
  • Priority: P5
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic,windows_nt
  • CPU: generic,x86
  • Submitted: 2000-07-07
  • Updated: 2011-10-31
  • Resolved: 2011-10-31
Description

Name: skT45625			Date: 07/07/2000


java version "1.2.2"
Classic VM (build 1.2.2-L, green threads, nojit)


Greetings.

[This is more of a Java language issue than directly related to the JDK,
but you guys seemed the best target out of the listing, most of which are
APIs.. :]

I would *love* to allow anonymous inner classes to access more than final
variables. Trying to use anonymous threads with ServerSockets and Sockets
is getting plain frustrating, and I wish I knew a better way of dealing
with the restrictions; however, I don't understand why the restriction on
allowing inner classes to access all variables.

Some simple code such as the following would be nice:

	for (int i=0;i<MAXCONNECTIONS;i++) {
		ServerSocket ss = new ServerSocket(port+i);
		Socket s = null;
		Thread t = new Thread() {
			run() {
				s = ss.accept(); // ignore Exceptions for the
				ss.close();      // moment...
				AnotherObject.processSocket(s);
			}
		};
		t.start();
	}

	AnotherObject.iterateOverAllSockets();

While I realize this trivial example could be beaten into working, the
application I am working on isn't yielding to my pounding. If anonymous
inner classes allowed access to more than just final variables, I wouldn't
need to pound on anything at all.

Thank you,
Seth Arnold,
###@###.###
(Review ID: 106927) 
======================================================================

Name: nt126004			Date: 09/18/2001


Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

I used the two classes below to simplify the problem.
Basically the variable x prints out no problem, however the variable y comes
out as null.

public class test
{
	final private int x = 10;
	public static void main(String[] args)
	{
		test t = new test();
	}
	
	public test()
	{
		final Integer y = new Integer(20);
		MPIterator mpi = new MPIterator()
		{
			void call()
			{
				System.out.println(y);
				System.out.println(x);
			}
		};
	}
}


abstract class MPIterator
{
	MPIterator()
	{
			call();
	}
	
	abstract void call();
}

This problem cropped up when we misused the abstract class and tried to access
variable x when it was not private, this compiled fine, but threw a
NullPointerException. Because we didn't fully understand how this was working
we replaced the variable x with variable y which was local to the method. This
would not compile unless the variable was made final. When we corrected this we
found that it would compile but that the value null was printed out.

Here is the output from the program as it is specified above:
null
10
(Review ID: 131868)
======================================================================

Comments
EVALUATION Proposals for new features in the Java programming language are no longer being accepted or maintained in the bug database at http://bugs.sun.com/. This also applies to proposals for new features in the Java Virtual Machine (that is, in the abstract JVM, as opposed to a JVM implementation like HotSpot). All proposals for new features should be made through the "JDK Enhancement - Proposal & Roadmap Process" described at http://openjdk.java.net/jeps/1. This specific request to change the Java programming language is related to the work of OpenJDK Project Lambda. It will be considered further by that project, not here. The bug database continues to accept and maintain submissions about technical errors in the design and specification of the Java programming language and the Java Virtual Machine.
31-10-2011

PUBLIC COMMENTS The legitimate uses of non-final locals in anonymous classes are those that use anonymous classes as closures. Multi-threading, as suggested, will not work because of race conditions on the shared locals. In fact, the motivating example given by the submitter is exactly the kind of code that motivated the restrictions. Overall, the change should be considered, but for different reasons.
15-08-2004

EVALUATION Rerouting to java/specification. william.maddox@Eng 2000-07-25 I agree that lifting the restriction would be desirable. It's a little disturbing that the motivating example given by the submitter is exactly the kind of code that motivated the restrictions. In fact, the legitimate uses of non-final locals in anonymous classes are those that use anonymous classes as closures. Multi-threading, as suggested, will not work because of race conditions on the shared locals. Overall, the change should be considered, but for different reasons. gilad.bracha@eng 2000-07-25
25-07-2000