Prev: Java work from home. Remote (telecommuting) jobs in Java.
Next: Zip question: Where are all the extra characters coming fromupon unzipping?
From: Tomas Mikula on 20 Oct 2009 18:59 On Tue, 20 Oct 2009 18:28:45 -0400, Eric Sosman wrote: > Daniel Pitts wrote: >> Eric Sosman wrote: >>> Tomas Mikula wrote: >>>> [...] >>>> 1. serialization frameworks. It is already required that a >>>> Serializable class has a no-arg constructor. But this is not required >>>> at compile time. >>> >>> You've said this a couple times, but are you sure it's true? >>> This class (with no no-arg constructor) appears to serialize and >>> deserialize just fine: >> >> Only the non-Serializable Base of a Serializable class requires a >> no-args constructor: [...] Ah, I was wrong with this. But this only means that the Java's serialization doesn't use _any_ constructor to create an object. Which means that it uses some tricks not available to the programmer (correct me if I am wrong). In your own serialization framework you would need to create the object being deserialized, so you would care about the constructors available on your class, not the superclass.
From: Arved Sandstrom on 20 Oct 2009 19:40 Eric Sosman wrote: > Daniel Pitts wrote: >> Eric Sosman wrote: >>> Tomas Mikula wrote: >>>> [...] >>>> 1. serialization frameworks. It is already required that a >>>> Serializable class has a no-arg constructor. But this is not >>>> required at compile time. >>> >>> You've said this a couple times, but are you sure it's true? >>> This class (with no no-arg constructor) appears to serialize and >>> deserialize just fine: >> >> Only the non-Serializable Base of a Serializable class requires a >> no-args constructor: [...] > > Right. Which means that if an interface could mandate a specific > constructor for its implementing classes, this capability would not > solve Serializable's problem at all: It's not the Serializable class > that needs the special constructor, but a superclass that *doesn't* > implement Serializable. If we get to the point where an interface > can impose requirements on the classes that *don't* implement it, I > think we've achieved absurdity ;-) > > There may yet be a reasonable use case for letting an interface > or abstract class require specified constructor signatures of the > implementing subclasses, but Serializable isn't it. Maybe it's just me, but if I want an abstract class to require specific constructor signatures of its subclasses, I give that abstract base class that constructor. :-) [ SNIP ] AHS
From: Lew on 20 Oct 2009 20:17 Tomas Mikula wrote: > 2. For calling static methods on generics. My example was > abstract class Vector<V extends Vector<V>>{ > /** returns a zero vector */ > public abstract static V zero(); > } This would be an extreme change to the semantics of Java generics, most likely very infeasible as stated. Type parameters are resolved per instance, and do not apply class-wide. How is it even possible for a class to know what type to use for 'V', when every instance of that class could have a different type replacement for it? -- Lew
From: Steven Simpson on 21 Oct 2009 01:10 Tomas Mikula wrote: > On Mon, 19 Oct 2009 19:26:41 +0100, Steven Simpson wrote: > >> class X implements static Runnable { >> public static void run() { ... } >> } >> > > Now if you had > > class Y extends X {...} > > would the compiler enforce that Y provides its own implementation of > static run() method? (My desirable answer would be YES.) > My initial answer is 'no'. Y$static would contain: public void run() { Y.run(); } ....which would just bind to X#run() if Y didn't provide its own #run(). However, I guess the compiler could enforce it, though I'm not sure if one would want that in all situations. In its favour, while Y instances might inherit behaviour available in X instances due to 'Y extends X', there's no reason for the static aspect of Y to inherit the static aspect of X, e.g. it does not necessarily follow that Y$static extends X$static, or that (X implements static Runnable && Y extends X => Y implements static Runnable). Hmm... > If you had an abstract class > abstract class X implements static Runnable {...}, > would the implementation of static method run() still be required? (My > desirable answer would be NO.) > I would say 'yes', if only since 'abstract' has never affected static methods. 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. For instance methods, where Y extends X, it's clear that having an X reference could mean invoking a Y object, i.e. you have a piece of code which syntactically only refers to type X but semantically could invoke Y: abstract class X { public abstract void doSomething(); } class Y extends X { ... } X ref = ...; ref.doSomething(); // this piece At run-time, you might be dealing with Y, but statically you have only X. When do you have an analogous case for static methods? In the dynamic-loading use-case, Y would be explicitly identified by name (and passed to Class#forName(String)). You then check dynamically that Y 'implements static Runnable' with a call to Class#meetsContract(Runnable.class). Anything you say about X is irrelevant. In the reified-generics case, you might have a class that requires a type parameter that 'implements static Runnable': class Banana<T extends static Runnable> { { T.run(); } } (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.) Then you write 'new Banana<Y>', and the compiler checks that Y 'implements static Runnable', and still X is not involved. Can you write an example where some code statically uses X and that it 'implements static Runnable', but could actually end up invoking Y#run()? >> It would work by the compiler generating an extra class when it saw >> 'implements static'. >> > > Somehow I feel that for consistency any class should support X.static, > not just when it 'implements static' some interface. Yes. For classes without any 'implements static', the proxy object that X.static ultimately evaluates to (and which Class#getContractor() returns) can just be an instance of Object, as there are no interfaces that it has to conform to. > But I'm curious what was the motivation for having X.static? If nothing else, just to ensure that there is a static, type-safe, compile-time way to obtain the proxy object. If you happen to know X statically, and that 'X implements static Z', and something accepted a Z, you could write doSomething(X.static). > I only see usability if it was > allowed to use it on type parameters: > > class MyClass<T static implements Runnable> { > ... > T.static.run(); > ... > } > As you noted before, this sort of thing seems to require reification, though it's pretty similar to something in Stefan's last topical blog entry, where he felt that something could be done without reification. >> 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. >> > > Or maybe X.static could just expand to X._static where the line > > public static final X$static _static = new X$static(); > > would be added to class X. > Good idea, though I don't think '_static' is an especially reserved name (is it?). 'static' would never clash with any real class member, and we're past syntactic analysis by now, so it should be expressible in bytecode. One problem might be that Class#getContractor() would have to reflectively look-up a static field on X, instead of just calling Class.forName("X$static").newInstance(). Also, there was an objection to increased object count, so creating on demand seemed worthwhile. Cheers! -- ss at comp dot lancs dot ac dot uk
From: Andreas Leitgeb on 21 Oct 2009 04:10
Arved Sandstrom <dcest61(a)hotmail.com> wrote: > Maybe it's just me, but if I want an abstract class to require specific > constructor signatures of its subclasses, I give that abstract base > class that constructor. :-) You may of course do that, but that doesn't put any constructor *requirements* upon the subclasses. |