John Rose wrote:
> Making Runtime and/or Runtime.load* final is an API change, which is
> harder to do than an implementation change.

I worry about compatibility a lot and my (selfish) reasoning is that it is 
better for the CCC to break someones code (there has to be someone somewhere 
that uses a subclass of Runtime, in combination with Unsafe.allocateInstance()) 
than for my implementation specific behavior to break the code.

I remembered that making the methods final isn't sufficient, because then they 
can still implement an interface method, which is also not great.

Note that this isn't a critical issue for me. Most code uses the static methods 
in System anyway and my current code also doesn't special case Runtime (meaning 
that it will use the normal stack walk mechanism).

> Given that Runtime.<init> is private, it seems to me that there is no
> way to execute an override of those load methods, even if one could
> (deviously) load a subclass into the JVM.  It would be valid behavior, I
> think, for the JVM to quietly refuse to override them, because there
> would be no way to observe the refusal.

Not for Java programs, but there are a lot of Java-like programs that assume 
the reference implementation.

> Note that the technique of a private <init> method is the recommended
> way to prevent instantiation of subclasses, and is used throughout the
> JDK.

Given the ability to create constructorless subclasses, it really should be 
combined with making the class final.

My current rules for @CallerID (which unlike @CallerSensitive is not just about 
semantics, but also about implementation strategy) allow it only to be used on 
static methods and instance methods in final classes (in theory constructors 
would also be allowed, but I didn't implement that since I didn't encounter any 
that were worthwhile). An implicit rule is that a @CallerID instance methods 
may not implement an interface method.

Another thought that occurred to me was that there should probably be a test 
that goes through rt.jar and makes sure no ACC_BRIDGE or ACC_SYNTHETIC methods 
call @CallerSensitive methods.

Regards,
Jeroen

Reply via email to