Re: abstract static methods (again)
Joshua Cranmer wrote:
On 10/18/2009 10:06 PM, Tomas Mikula wrote:
I have searched this group for "abstract static methods" and found a
couple of threads, [...]
I saw a more detailed proposal at <http://kijaro.dev.java.net>, which
included a prototype implementation.
....which we didn't complete, btw. The bits missing (described below) are:
* the generation of X$static,
* the expansion of X.static,
* verification of classes claiming to 'implement static' interfaces.
So, just the important bits! ;-) I have no idea how to proceed with
those (lack of familiarity with javac internals), and Stefan was not
optimistic about the feature's prospects (so understandably he didn't
want to put much more effort into it).
The specification for said stuff is linked here:
<http://www.jroller.com/jadda/entry/meta_interfaces_revisited>.
I shall summarize here, as the plan below is not expected to achieve as
much as all the ideas discussed in the blog.
The current plan is to support 'static' on the implementation of whole
interfaces, rather than on individual methods. Given a class such as:
class X implements static Runnable {
public static void run() { ... }
}
....then you could write X.static, and get a normal Runnable on which you
could invoke run(), and it would actually invoke X.run(). If X was
loaded dynamically, you could get the same Runnable:
Class<?> clazz = Class.forName("X");
if (clazz.meetsContract(Runnable.class)) {
Runnable r = clazz.contractOn(Runnable.class);
...
}
So you can invoke a static method on the dynamically loaded class
without method reflection. And X can be checked at compile-time that it
provides required static methods.
It would work by the compiler generating an extra class when it saw
'implements static'. For X, that would be:
class X$static implements Runnable {
public void run() {
X.run();
}
}
Each Class object would have a proxy object (created on demand), which
would be an instance of X$static in this case. By being loaded with the
same ClassLoader as X, the X.run() call would bind to the correct
X#run() static method.
An expression such as:
X.static
....would expand to:
(X$static) X.class.getContractor()
Class#getContractor() would create the proxy or recover a cached one.
Maybe the OP could check whether his requirements would be met by such a
feature. It might fall short, but when problems are expressed as a lack
of static interface methods, I usually start thinking of defining
regular interfaces with the necessary methods (e.g. abstract factories),
and end up with something more powerful anyway (e.g. decoupled
construction and use of a class). The 'implements static' feature is
just a way of doing such things as factories without needing to overtly
create a 'dummy' factory object.
Cheers!
--
ss at comp dot lancs dot ac dot uk