Re: abstract static methods (again)
Tomas Mikula wrote:
On Wed, 21 Oct 2009 06:10:02 +0100, Steven Simpson wrote:
(Aside: I don't see a point in distinguishing between 'extends' and
'implements' on a type parameter, as only one relationship needs to be
expressed, i.e. Class#isAssignableFrom(Class), which is the same whether
you're dealing with interfaces or classes.)
By 'implements' I meant what you mean by 'extends static'. I just needed
to distinguish it from 'extends' without introducing new keyword.
Okay, I did wonder. :-)
My intuition was that X.static should allow to invoke any static method
of X, not just the ones that appear in some interface that X statically
implements:
class X implements static Runnable {
public static void run(){...}
public static void another(){...}
}
X.static.another().
Not that this would be of any use, it just would feel natural.
It had occurred to me too, but without a pressing need (and so no clear
requirements to help specify it exactly), it seems to be 'future work'.
Then X.static
(in the source code)
could just expand to X.static
(in the compiler's internal structures, where 'static' is just a field
name, not a keyword)
(So, yes, that's what it would expand to in the case of a static field
itself called 'static'.)
Was there any other useful use of Class#getContractor() other than with
resolving X.static? If it now was not necessary for that, getContractor
could be omitted completely.
Class#getConstructor() as it stands is responsible for ensuring that
only proxy object exists per Class object. So if 'X implements static
Y, static Z':
Class<?> clazz = Class.forName("X");
assert clazz.contractOn(Y.class) == clazz.contractOn(Z.class);
assert clazz.contractOn(Y.class) == X.static;
You suggested this implementation (for when not using the 'static'
field, I presume):
<T> T contractOn(Class<T> clazz){
return clazz.cast(Class.forName(this.getName() +
"$static").newInstance());
}
....which would create as many instances as asked for. You could still
fold the caching into it, but since X.static requires that functionality
when there is no 'static' field, it is factored out as
Class#getConstructor().
If you follow the 'static' field approach:
public static final X$static static = new X$static();
Class#contractOn(Class) becomes:
<T> T contractOn(Class<T> clazz) {
return clazz.cast(getField("static").get(null));
}
....which is a reflective access. You could cache it here too, but
surely the main point of using the static field called 'static' is not
to have to install a caching mechanism.
--
ss at comp dot lancs dot ac dot uk