Prev: Java work from home. Remote (telecommuting) jobs in Java.
Next: Zip question: Where are all the extra characters coming fromupon unzipping?
From: Steven Simpson on 21 Oct 2009 13:05 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
From: Steven Simpson on 21 Oct 2009 13:05 posting-account=pAbxHwoAAAADCfRr12ntKYVMSzbDntdj Tomas Mikula wrote: > On Wed, 21 Oct 2009 06:10:02 +0100, Steven Simpson wrote: > >> In fact, since you expect (from the previous question) that any Y which >> extends X must provide its own static run(), I don't see a point in >> requiring X to 'implements static Runnable' if it's only going to leave >> the implementation to a base class. >> > > The point would be to enforce the subclasses to 'implement static' > Runnable. Consider again an abstract class Vector with static method > zero(), which should return a zero vector. Vector alone doesn't need > (even can't reasonably) implement zero(), but it wants to enforce its > implementation in all concrete subclasses. I anticipated shortly after posting that your Vector example might be what you were getting at. Here's how I think it would go (assuming reified generics). Your original declaration: class MyClass<V extends Vector<V>> { public void someMethod(){ V v = V.zero(); ... } } So, on some class whose full implementation you don't know about, you expect a (V zero()) method - so define an interface type for that: interface Zero<V> { V zero(); } Now express two constraints on the type provided to MyClass: class MyClass<V extends Vector<V> & V extends static Zero<V>> { public void someMethod(){ V v = V.zero(); ... } } Does that work for you? If so, there's no need to put an 'abstract static' on Vector. It's only MyClass that imposes the requirement. Other classes analogous to MyClass might not need to call zero(), and could use extensions of Vector that don't also 'implement static Zero' - such extensions could not exist if Vector imposed the requirement on all its descendants. -- ss at comp dot lancs dot ac dot uk
From: Tomas Mikula on 21 Oct 2009 14:01 On Wed, 21 Oct 2009 18:05:33 +0100, Steven Simpson wrote: > posting-account=pAbxHwoAAAADCfRr12ntKYVMSzbDntdj > > Tomas Mikula wrote: >> On Wed, 21 Oct 2009 06:10:02 +0100, Steven Simpson wrote: >> >>> In fact, since you expect (from the previous question) that any Y >>> which extends X must provide its own static run(), I don't see a point >>> in requiring X to 'implements static Runnable' if it's only going to >>> leave the implementation to a base class. >>> >>> >> The point would be to enforce the subclasses to 'implement static' >> Runnable. Consider again an abstract class Vector with static method >> zero(), which should return a zero vector. Vector alone doesn't need >> (even can't reasonably) implement zero(), but it wants to enforce its >> implementation in all concrete subclasses. > > I anticipated shortly after posting that your Vector example might be > what you were getting at. Here's how I think it would go (assuming > reified generics). Your original declaration: > > class MyClass<V extends Vector<V>> { > public void someMethod(){ > V v = V.zero(); > ... > } > } > > So, on some class whose full implementation you don't know about, you > expect a (V zero()) method - so define an interface type for that: > > interface Zero<V> { > V zero(); > } > > Now express two constraints on the type provided to MyClass: > > class MyClass<V extends Vector<V> & V extends static Zero<V>> { > public void someMethod(){ > V v = V.zero(); > ... > } > } > > Does that work for you? Yes, that would work for me. But you need to add a new syntax, namely the '&' in the generic parameters.
From: Steven Simpson on 21 Oct 2009 13:58 Steven Simpson wrote: > ...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(). > D'oh! getContractor()!! -- ss at comp dot lancs dot ac dot uk
From: Andreas Leitgeb on 21 Oct 2009 14:47
Tomas Mikula <tomas.mikula(a)gmail.com> wrote: >> MyBase mb = (MyBase)Class.forName("MyImpl").newInstance(); > I was aware of this simple and only example where the convention can be > checked at runtime quite concisely. What if I want to use another > constructor and, say, two static methods. Things get a little messy. The task itself is messy, and reflection is the tool designed to handle the mess :-) . Any other tool wouldn't be less messy, but they might move the mess somewhere else - e.g. create wrapper-classes to do the static calls. About this "each class (of some hierarchy) must provide its own implementation of certain static methods" thing: This is obviously even stricter as abstract virtual methods, which, once implemented are inherited by subclasses without them having to reimplement again. Is it just the factory-pattern, that drove you to this idea, or are there also other patterns that you think would benefit from enforced static method implementations? Or is it perhaps just a first step before requesting also special virtual methods that need to be overridden in each subclass? |