abstract static methods (again)

Discussion in 'Java' started by Tomas Mikula, Oct 19, 2009.

  1. Tomas Mikula

    Tomas Mikula Guest

    I have searched this group for "abstract static methods" and found a
    couple of threads, but I think none of them was discussing the kind of
    semantics I am going to describe. As you might have guessed, I believe it
    would be useful :). I further believe it is fully complatible with the
    current language, but there might be caveats I have overlooked. I'm
    wonder if you would find it as useful as I do and if you see any problems
    with it. I know it is a long post and some parts may be difficult to
    understand. Therefore I will be thankful if you can read it all and think
    about it.

    By "abstract static method" I refer to either a static method in an
    interface or an abstract static method of an abstract class.

    Put shortly, a declaration of an abstract static method in interface J
    (resp. in abstract class A) would mean that any class implementing J
    (resp. extending A) must either provide its _own_ implementation of that
    static method, or itself be abstract.

    Note 1: There would still be no inheritance of static methods.
    Note 2: Semantics of calling static methods on instances would remain
    unchanged, i.e. static methods are still not virtual.
    Note 3: The following would be a compile-time error:

    interface J {
    public static void f();
    }
    class X implements J {
    public static void f(){...}
    }
    class Y extends X {
    }
    // ERROR: class Y does not provide
    // its _own_ implementation of f()

    Note 4: Abstract constructors could be allowed, too.

    interface Serializable {
    public abstract Serializable();
    }

    This would require each implementation of Serializable to provide a
    public no-arg constructor.
    (Maybe the following would be a better syntax:
    interface Serializable<S extends Serializable> {
    public abstract S();
    }
    )


    Now I present two examples where it would be useful.

    (1) Eliminate or reduce the use of reflection in serialization frameworks.
    One example was given in Note 4 --- the presence of no-arg constructor in
    a serializable class would be checked at compile-time rather than at run-
    time.

    For a more sophisticated usage some new API and additional support from
    compiler is required. (The following may not be the best way to extend
    the API, but I hope it will serve well for illustration.)

    Imagine a new magic class Implementation<T>. This class will have no
    methods on its own, but on its instances we will be able to call the same
    methods as on the class T. (For this, the compiler magic would be
    necessary.)

    Example:

    interface J {
    J(int x);
    static void f();
    void g();
    }

    class A implements J {
    A(int x){...}
    static void f(){...}
    void g(){...}
    }

    Implementation<J> I = A.class.asImplementationOf(J.class);
    I.new(5); // OK, calling the constructor A(int x)
    I.f(); // OK, calling static method A.f()
    I.g(); // ERROR, calling an instance method without an instance of J

    Notice extending the Class API by adding new method
    <T> Implementation<T> asImplementationOf(Class<T> clazz);
    The restriction would apply that the type T is known at compile time.

    Now back to usage in serialization frameworks. The above API would
    automate the verification that all required constructors and static
    methods are present in a class:

    interface MySerializable<S extends MySerializable<S>> {
    public static S readObject(ObjectInputStream in);
    }

    Class<?> cls = Class.forName("com.example.MySerializableClass");
    Implementation<MySerializable> M =
    cls.asImplementationOf(MySerializable.class);
    MySerializable obj = M.readObject(in);

    Note that the verification that MySerializableClass really implements
    MySerializable interface would be automatically done in the
    Class.asImplementationOf() method, thus saving much of the reflection
    code.


    (2) The second use case is with generics, but would require reified
    generics (which I hope will appear in some future version of Java).

    Suppose you have an abstract class Vector which represents a vector in a
    vector space (don't confuse with java.util.Vector) and a few
    implementations, like Vector2D and Vector3D.

    abstract class Vector<V extends Vector<V>> {
    public abstract V add(V v); // returns the sum of v and this
    ...
    }

    class Vector2D extends Vector<Vector2D> {
    public static Vector2D zero(); // returns (0,0)
    ...
    }

    class Vector3D extends Vector<Vector3D> {
    public static Vector3D zero(); // returns (0,0,0)
    ...
    }

    Now let's have a generic class that will use vectors and do operations on
    them, but doesn't really care about their actual dimension. So it will
    work with abstract type Vector. But for some operations it may be
    necessary to obtain the zero vector, without explicitely knowing the
    actual type of vector. We may want to write something like this:

    class MyClass<V extends Vector<V>> {
    public void someMethod(){
    V v = V.zero();
    ...
    }
    }

    This is of course not possible, but could be made possible if Vector
    specified abstract static method zero():

    abstract class Vector<V extends Vector<V>> {
    public static abstract V zero();
    public abstract V add(V v);
    ...
    }

    We would further change the declaration of MyClass to

    class MyClass<V implements Vector<V>> {
    ...
    }

    The keywork extends was exchanged for implements (another syntax
    extension). The compiler would know that a type parameter V that fully
    implements all abstract static methods of Vector is required (so, for
    example, Vector itself would not be a valid type parameter of MyClass).
    Tomas Mikula, Oct 19, 2009
    #1
    1. Advertising

  2. Tomas Mikula

    Tomas Mikula Guest

    On Sun, 18 Oct 2009 19:19:55 -0700, Peter Duniho wrote:

    > Tomas Mikula wrote:
    >> I have searched this group for "abstract static methods" and found a
    >> couple of threads, but I think none of them was discussing the kind of
    >> semantics I am going to describe. As you might have guessed, I believe
    >> it would be useful :). [...]

    >
    > You aren't the first. However, in C++, C#, Java, and languages like
    > them, you simply are never going to have methods that are both virtual
    > and static. And since abstract implies virtual, that rules out abstract
    > static methods too.


    I'm not talking about virtual static methods. In this case, abstract
    would not imply virtual. My second use case could most probably be
    accomplished in C++ by Concepts (though Concepts didn't make it to C+
    +0x). In fact, it is achievable with current C++ templates, only without
    compile time checking --- it is possible to call T::staticMethod() where
    T is a template parameter.
    Tomas Mikula, Oct 19, 2009
    #2
    1. Advertising

  3. On 19 Paź, 04:06, Tomas Mikula <> wrote:
    > I have searched this group for "abstract static methods" and found a
    > couple of threads, but I think none of them was discussing the kind of
    > semantics I am going to describe. As you might have guessed, I believe it
    > would be useful :). I further believe it is fully complatible with the
    > current language, but there might be caveats I have overlooked. I'm
    > wonder if you would find it as useful as I do and if you see any problems
    > with it. I know it is a long post and some parts may be difficult to
    > understand. Therefore I will be thankful if you can read it all and think
    > about it.


    Hi,
    Interesting but I doubt it is going to be useful. First of all,
    because statics should remain non-inheritable, static abstract
    actually forces each subclass to implement its own definition -
    extreme nuisance in my opinion. Example with generics can easily be
    substituted by some kind of "trait" parameter or suitable simple
    design pattern (for example Factory), or even with classic sub-typing
    (zero vector needs not know its dimension, it can simply 'answer' with
    neutral element of the ring on which it is constructed for each and
    every component query), no big win here either (eliminating type
    erasure is extremely welcome but for other reasons). One big advantage
    of inheritance is, in my opinion, that it enables you to compose more
    specialized classes from generic ones, it is easy to imagine algebraic
    ordering relation between types based on inheritance. Your version of
    statics breaks this assumption without promise of any reward in
    exchange.
    However, I like the idea of "interface constructor". It might be handy
    to force every client to provide necessary piece of data. To be more
    useful for this purpose I'd postulate to create the rule which says
    that every derived constructor has to call this 'interface
    constructor'. But still, no big deal. It is possible to impose
    semantics I am talking about with or without it.
    Marcin Rzeźnicki, Oct 19, 2009
    #3
  4. 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, but I think none of them was discussing the kind of
    > semantics I am going to describe. As you might have guessed, I believe it
    > would be useful :). I further believe it is fully complatible with the
    > current language, but there might be caveats I have overlooked. I'm
    > wonder if you would find it as useful as I do and if you see any problems
    > with it. I know it is a long post and some parts may be difficult to
    > understand. Therefore I will be thankful if you can read it all and think
    > about it.


    I saw a more detailed proposal at <http://kijaro.dev.java.net>, which
    included a prototype implementation. The specification for said stuff is
    linked here: <http://www.jroller.com/jadda/entry/meta_interfaces_revisited>.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Oct 19, 2009
    #4
  5. Tomas Mikula <> wrote:
    > I have searched this group for "abstract static methods" ...
    > ... presence of no-arg constructor in a serializable class would be
    > checked at compile-time rather than at run-time.


    I think this is easily misunderstood. The newly possible compiletime
    check would be for compiling the *concrete class* whose name you later
    intend to specify dynamically at runtime. This does have some merit.

    Still no compiletime check would of course be possible at the place
    where you'd *use* that class dynamically, so nothing at all can be
    helped about the reflection-part of this story.

    There's still a slight "problem" with abstract static methods:
    With respect to static members, *every* class is concrete.
    Maybe you thought about static "create"-methods, as alternative
    to enforced constructors?
    Andreas Leitgeb, Oct 19, 2009
    #5
  6. Tomas Mikula

    Tomas Mikula Guest

    On Mon, 19 Oct 2009 07:29:24 +0000, Andreas Leitgeb wrote:

    > Tomas Mikula <> wrote:
    >> I have searched this group for "abstract static methods" ... ...
    >> presence of no-arg constructor in a serializable class would be checked
    >> at compile-time rather than at run-time.

    >
    > I think this is easily misunderstood. The newly possible compiletime
    > check would be for compiling the *concrete class* whose name you later
    > intend to specify dynamically at runtime. This does have some merit.
    >
    > Still no compiletime check would of course be possible at the place
    > where you'd *use* that class dynamically, so nothing at all can be
    > helped about the reflection-part of this story.


    The idea here was to automate the reflection. Suppose a class is required
    to have many static methods. Instead of checking if they are actually
    present and have the correct signature manually, the method
    Class.asImplementationOf(MyInterface.class) would do all the checking for
    me.

    > There's still a slight "problem" with abstract static methods: With
    > respect to static members, *every* class is concrete. Maybe you thought
    > about static "create"-methods, as alternative to enforced constructors?


    If an abstract class MyClass does not have an implementation of a static
    abstract method staticMethod() specified in its superclass/interface, it
    can be detected in both the direct use and through reflection:

    MyClass.staticMethod(); // this would be a compile-time error
    Class.forName("MyClass").asImplementationOf(MyInterface.class);
    // this would be a run-time error

    My view is that with respect to abstract static members, not every class
    would be concrete.
    Tomas Mikula, Oct 19, 2009
    #6
  7. Tomas Mikula

    Tomas Mikula Guest

    On Sun, 18 Oct 2009 19:58:43 -0700, Marcin Rzeźnicki wrote:

    > On 19 Paź, 04:06, Tomas Mikula <> wrote:
    >> I have searched this group for "abstract static methods" and found a
    >> couple of threads, but I think none of them was discussing the kind of
    >> semantics I am going to describe. As you might have guessed, I believe
    >> it would be useful :). I further believe it is fully complatible with
    >> the current language, but there might be caveats I have overlooked. I'm
    >> wonder if you would find it as useful as I do and if you see any
    >> problems with it. I know it is a long post and some parts may be
    >> difficult to understand. Therefore I will be thankful if you can read
    >> it all and think about it.

    >
    > Hi,
    > Interesting but I doubt it is going to be useful. First of all, because
    > statics should remain non-inheritable, static abstract actually forces
    > each subclass to implement its own definition - extreme nuisance in my
    > opinion.


    Yes (unless the subclass is abstract). I think in some cases it is
    reasonable (as with the enforced no-arg constructor in Serializable, or
    some other serialization static methods. For example, if I want to
    deserialize an immutable object, I need to do it by a static method or a
    special constructor, because the non-static readObject(...) method in
    Java's serialization API is a mutator method. In my opinion it is
    reasonable to enforce own implementation of a (de)serialization method).

    > Example with generics can easily be substituted by some kind of
    > "trait" parameter


    Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    I would call the zero() method on some instance?
    Like myDummyVector.zero()?

    > or suitable simple design pattern (for example
    > Factory), or even with classic sub-typing (zero vector needs not know
    > its dimension, it can simply 'answer' with neutral element of the ring
    > on which it is constructed for each and every component query),


    Allowing operations between a concrete vector and this general zero
    vector would require to also allow operations between 2D and 3D vetors -
    the original type safety would disappear.

    > no big
    > win here either (eliminating type erasure is extremely welcome but for
    > other reasons). One big advantage of inheritance is, in my opinion, that
    > it enables you to compose more specialized classes from generic ones, it
    > is easy to imagine algebraic ordering relation between types based on
    > inheritance. Your version of statics breaks this assumption without
    > promise of any reward in exchange.


    I don't see how it breaks this relation between classes. Also now it is
    possible to hide supertype's static methods by own implementation. I
    would only add that in some cases this hiding would be required.
    Tomas Mikula, Oct 19, 2009
    #7
  8. On 19 Paź, 13:08, Tomas Mikula <> wrote:
    > On Sun, 18 Oct 2009 19:58:43 -0700, Marcin Rzeźnicki wrote:
    > > On 19 Paź, 04:06, Tomas Mikula <> wrote:
    > >> I have searched this group for "abstract static methods" and found a
    > >> couple of threads, but I think none of them was discussing the kind of
    > >> semantics I am going to describe. As you might have guessed, I believe
    > >> it would be useful :). I further believe it is fully complatible with
    > >> the current language, but there might be caveats I have overlooked. I'm
    > >> wonder if you would find it as useful as I do and if you see any
    > >> problems with it. I know it is a long post and some parts may be
    > >> difficult to understand. Therefore I will be thankful if you can read
    > >> it all and think about it.

    >
    > > Hi,
    > > Interesting but I doubt it is going to be useful. First of all, because
    > > statics should remain non-inheritable, static abstract actually forces
    > > each subclass to implement its own definition - extreme nuisance in my
    > > opinion.

    >
    > Yes (unless the subclass is abstract). I think in some cases it is
    > reasonable (as with the enforced no-arg constructor in Serializable, or
    > some other serialization static methods. For example, if I want to
    > deserialize an immutable object, I need to do it by a static method or a
    > special constructor, because the non-static readObject(...) method in
    > Java's serialization API is a mutator method. In my opinion it is
    > reasonable to enforce own implementation of a (de)serialization method).
    >


    Hi, possibly it is reasonable, but what is wrong with how it is done
    today (readObject/writeObject) which you are not required to implement
    if default behavior suffices?

    > > Example with generics can easily be substituted by some kind of
    > > "trait" parameter

    >
    > Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    > I would call the zero() method on some instance?
    > Like myDummyVector.zero()?
    >


    I borrowed the terminology from C++. More or less, you add type
    parameter (let's say <Zero extends ZeroVector>) which has a method
    like getZeroVector() (strictly speaking ZeroVector has this method).
    Actual type parameter provides concrete implementation.

    > > or suitable simple design pattern (for example
    > > Factory), or even with classic sub-typing (zero vector needs not know
    > > its dimension, it can simply 'answer' with neutral element of the ring
    > > on which it is constructed for each and every component query),

    >
    > Allowing operations between a concrete vector and this general zero
    > vector would require to also allow operations between 2D and 3D vetors -
    > the original type safety would disappear.
    >


    I don't get it, could you provide an example?

    > >  no big
    > > win here either (eliminating type erasure is extremely welcome but for
    > > other reasons). One big advantage of inheritance is, in my opinion, that
    > > it enables you to compose more specialized classes from generic ones, it
    > > is easy to imagine algebraic ordering relation between types based on
    > > inheritance. Your version of statics breaks this assumption without
    > > promise of any reward in exchange.

    >
    > I don't see how it breaks this relation between classes. Also now it is
    > possible to hide supertype's static methods by own implementation. I
    > would only add that in some cases this hiding would be required.


    I was not very clear, it was late when I was writing :) I guess what
    I was trying to say was that you can impose ordering based on
    specialization (as opposed to parent-child relationship). Each class
    in an inheritance chain either extends or redefines partially its
    ancestor (I am using 'or' as logical or). Therefore each class is
    either more specialized (if redefinition occurs and it accepts
    stronger contract, as in Rectangle->Square) or equally specialized (if
    extension occurs and all redefinitions do not change contract - I
    treat extension as an interface extension so that class can be used
    _additionally_ in different context). Your proposal forces implementor
    to provide implementation for non-inheritable method, so it really
    can't take any benefit from redefinitions up the chain. Therefore all
    concrete classes are at most equally specialized as their context of
    usage is determined by a static method. So it does not play well with
    most "inheritance patterns". That's how I see it.
    Marcin Rzeźnicki, Oct 19, 2009
    #8
  9. On 19 Pa¼, 14:19, Marcin Rze¼nicki <> wrote:
    > On 19 Pa¼, 13:08, Tomas Mikula <> wrote:
    >
    > > > Example with generics can easily be substituted by some kind of
    > > > "trait" parameter

    >
    > > Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    > > I would call the zero() method on some instance?
    > > Like myDummyVector.zero()?

    >
    > I borrowed the terminology from C++. More or less, you add type
    > parameter (let's say <Zero extends ZeroVector>) which has a method
    > like getZeroVector() (strictly speaking ZeroVector has this method).
    > Actual type parameter provides concrete implementation.
    >


    I forgot to clarify - you are right, all in all you call zero() method
    on some instance :)
    Marcin Rze¼nicki, Oct 19, 2009
    #9
  10. Tomas Mikula

    Tomas Mikula Guest

    On Oct 19, 2:19 pm, Marcin Rze¼nicki <>
    wrote:
    > On 19 Pa¼, 13:08, Tomas Mikula <> wrote:
    >
    >
    >
    > > On Sun, 18 Oct 2009 19:58:43 -0700, Marcin Rze¼nicki wrote:
    > > > On 19 Pa¼, 04:06, Tomas Mikula <> wrote:
    > > >> I have searched this group for "abstract static methods" and found a
    > > >> couple of threads, but I think none of them was discussing the kind of
    > > >> semantics I am going to describe. As you might have guessed, I believe
    > > >> it would be useful :). I further believe it is fully complatible with
    > > >> the current language, but there might be caveats I have overlooked. I'm
    > > >> wonder if you would find it as useful as I do and if you see any
    > > >> problems with it. I know it is a long post and some parts may be
    > > >> difficult to understand. Therefore I will be thankful if you can read
    > > >> it all and think about it.

    >
    > > > Hi,
    > > > Interesting but I doubt it is going to be useful. First of all, because
    > > > statics should remain non-inheritable, static abstract actually forces
    > > > each subclass to implement its own definition - extreme nuisance in my
    > > > opinion.

    >
    > > Yes (unless the subclass is abstract). I think in some cases it is
    > > reasonable (as with the enforced no-arg constructor in Serializable, or
    > > some other serialization static methods. For example, if I want to
    > > deserialize an immutable object, I need to do it by a static method or a
    > > special constructor, because the non-static readObject(...) method in
    > > Java's serialization API is a mutator method. In my opinion it is
    > > reasonable to enforce own implementation of a (de)serialization method)..

    >
    > Hi, possibly it is reasonable, but what is wrong with how it is done
    > today (readObject/writeObject) which you are not required to implement
    > if default behavior suffices?


    I'm saying it is wrong, but just don't like that the implementation
    requires a lot of reflection. (I don't mind that implementation of
    statndard Java API requires reflection, because someone has already
    implemented it for me. But if I want to create my own serialization
    framework (e.g. for xml serialization), I need to do a lot of
    reflection which could be automated.) Probably one thing I find wrong
    with readObject - as I already mentioned, it prevents the object to be
    immutable. Though this could also be solved by declaring it static and
    use reflection.

    >
    > > > Example with generics can easily be substituted by some kind of
    > > > "trait" parameter

    >
    > > Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    > > I would call the zero() method on some instance?
    > > Like myDummyVector.zero()?

    >
    > I borrowed the terminology from C++. More or less, you add type
    > parameter (let's say <Zero extends ZeroVector>) which has a method
    > like getZeroVector() (strictly speaking ZeroVector has this method).
    > Actual type parameter provides concrete implementation.


    I don't see how this would help. Would I call Zero.getZeroVector()?
    Probably you meant something else because this leads to the same
    problem with calling static method getZeroVector() on a type
    parameter. Could you provide an example?

    > > > or suitable simple design pattern (for example
    > > > Factory), or even with classic sub-typing (zero vector needs not know
    > > > its dimension, it can simply 'answer' with neutral element of the ring
    > > > on which it is constructed for each and every component query),

    >
    > > Allowing operations between a concrete vector and this general zero
    > > vector would require to also allow operations between 2D and 3D vetors -
    > > the original type safety would disappear.

    >
    > I don't get it, could you provide an example?


    If I understood well, you meant something like this:

    Class Vector {
    public static Vector getZeroVector(){
    return someSpecialZeroVectorInstance;
    }
    public abstract Vector add(Vector v);
    }

    Class Vector2D {
    public Vector add(Vector v){...}
    ...
    }

    class MyClass<V extends Vector> {
    ...
    V v; // V is some concrete class, such as Vector2D
    ...
    Vector zero = Vector.getZeroVector();
    v.add(zero); // adding a general Vector zero to concrete v
    // if this is allowed, then also the following is
    v.add(new Vector3D(1,2,3)); // summing 2D and 3D vector
    ...
    }

    > > >  no big
    > > > win here either (eliminating type erasure is extremely welcome but for
    > > > other reasons). One big advantage of inheritance is, in my opinion, that
    > > > it enables you to compose more specialized classes from generic ones, it
    > > > is easy to imagine algebraic ordering relation between types based on
    > > > inheritance. Your version of statics breaks this assumption without
    > > > promise of any reward in exchange.

    >
    > > I don't see how it breaks this relation between classes. Also now it is
    > > possible to hide supertype's static methods by own implementation. I
    > > would only add that in some cases this hiding would be required.

    >
    > I was not very clear, it was late when I was writing :) I guess what
    > I was trying to say was that you can impose ordering based on
    > specialization (as opposed to parent-child relationship). Each class
    > in an inheritance chain either extends or redefines partially its
    > ancestor (I am using 'or' as logical or). Therefore each class is
    > either more specialized (if redefinition occurs and it accepts
    > stronger contract, as in Rectangle->Square) or equally specialized (if
    > extension occurs and all redefinitions do not change contract - I
    > treat extension as an interface extension so that class can be used
    > _additionally_ in different context). Your proposal forces implementor
    > to provide implementation for non-inheritable method, so it really
    > can't take any benefit from redefinitions up the chain. Therefore all
    > concrete classes are at most equally specialized as their context of
    > usage is determined by a static method. So it does not play well with
    > most "inheritance patterns". That's how I see it.


    Now I don't get it. Can you provide an example where you have a class
    and its specialized subclass and adding an abstract static method to
    their interface removes/prohibits this specialization?
    Tomas Mikula, Oct 19, 2009
    #10
  11. On 19 Pa¼, 15:06, Tomas Mikula <> wrote:
    > On Oct 19, 2:19 pm, Marcin Rze 1/4 nicki <>
    > wrote:
    >
    >
    >
    > > On 19 Pa 1/4, 13:08, Tomas Mikula <> wrote:

    >
    > > > On Sun, 18 Oct 2009 19:58:43 -0700, Marcin Rze 1/4 nicki wrote:
    > > > > On 19 Pa 1/4, 04:06, Tomas Mikula <> wrote:
    > > > >> I have searched this group for "abstract static methods" and found a
    > > > >> couple of threads, but I think none of them was discussing the kind of
    > > > >> semantics I am going to describe. As you might have guessed, I believe
    > > > >> it would be useful :). I further believe it is fully complatible with
    > > > >> the current language, but there might be caveats I have overlooked.. I'm
    > > > >> wonder if you would find it as useful as I do and if you see any
    > > > >> problems with it. I know it is a long post and some parts may be
    > > > >> difficult to understand. Therefore I will be thankful if you can read
    > > > >> it all and think about it.

    >
    > > > > Hi,
    > > > > Interesting but I doubt it is going to be useful. First of all, because
    > > > > statics should remain non-inheritable, static abstract actually forces
    > > > > each subclass to implement its own definition - extreme nuisance in my
    > > > > opinion.

    >
    > > > Yes (unless the subclass is abstract). I think in some cases it is
    > > > reasonable (as with the enforced no-arg constructor in Serializable, or
    > > > some other serialization static methods. For example, if I want to
    > > > deserialize an immutable object, I need to do it by a static method or a
    > > > special constructor, because the non-static readObject(...) method in
    > > > Java's serialization API is a mutator method. In my opinion it is
    > > > reasonable to enforce own implementation of a (de)serialization method).

    >
    > > Hi, possibly it is reasonable, but what is wrong with how it is done
    > > today (readObject/writeObject) which you are not required to implement
    > > if default behavior suffices?

    >
    > I'm saying it is wrong, but just don't like that the implementation
    > requires a lot of reflection. (I don't mind that implementation of
    > statndard Java API requires reflection, because someone has already
    > implemented it for me. But if I want to create my own serialization
    > framework (e.g. for xml serialization), I need to do a lot of
    > reflection which could be automated.) Probably one thing I find wrong
    > with readObject - as I already mentioned, it prevents the object to be
    > immutable. Though this could also be solved by declaring it static and
    > use reflection.
    >
    >


    Yes, but someone did it for you either - JAXB, xStreams etc. This is
    not a type of work you do day-in day-out, so benefits are rarely to be
    seen

    >
    > > > > Example with generics can easily be substituted by some kind of
    > > > > "trait" parameter

    >
    > > > Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    > > > I would call the zero() method on some instance?
    > > > Like myDummyVector.zero()?

    >
    > > I borrowed the terminology from C++. More or less, you add type
    > > parameter (let's say <Zero extends ZeroVector>) which has a method
    > > like getZeroVector() (strictly speaking ZeroVector has this method).
    > > Actual type parameter provides concrete implementation.

    >
    > I don't see how this would help. Would I call Zero.getZeroVector()?
    > Probably you meant something else because this leads to the same
    > problem with calling static method getZeroVector() on a type
    > parameter. Could you provide an example?
    >


    OK
    public class MyVector<T, Zero extends ZeroVector> extends Vector2D<T>
    {
    ....
    public MyVector(Zero zero) { this.zero = zero; }
    ....
    }

    MyVector<Integer, Zero2D> vec = new MyVector(Vector2D.zero());


    > > > > or suitable simple design pattern (for example
    > > > > Factory), or even with classic sub-typing (zero vector needs not know
    > > > > its dimension, it can simply 'answer' with neutral element of the ring
    > > > > on which it is constructed for each and every component query),

    >
    > > > Allowing operations between a concrete vector and this general zero
    > > > vector would require to also allow operations between 2D and 3D vetors -
    > > > the original type safety would disappear.

    >
    > > I don't get it, could you provide an example?

    >
    > If I understood well, you meant something like this:
    >
    > Class Vector {
    > public static Vector getZeroVector(){
    > return someSpecialZeroVectorInstance;
    > }
    > public abstract Vector add(Vector v);
    >
    > }
    >
    > Class Vector2D {
    > public Vector add(Vector v){...}
    > ...
    >
    > }
    >
    > class MyClass<V extends Vector> {
    > ...
    > V v; // V is some concrete class, such as Vector2D
    > ...
    > Vector zero = Vector.getZeroVector();
    > v.add(zero); // adding a general Vector zero to concrete v
    > // if this is allowed, then also the following is
    > v.add(new Vector3D(1,2,3)); // summing 2D and 3D vector
    > ...
    >
    >
    >
    > }


    Right but implementation of addition surely checks for this case,
    doesn't it?
    public void add(Vector<? extends T> v) { if (v.getDimension() !=
    this.getDimension() ) throw new IllegalArgumentException(); }
    So it suffices to have a factory method for appropriate zero vectors
    Vector zero = Vector.getZeroVector(2);


    > > > > no big
    > > > > win here either (eliminating type erasure is extremely welcome but for
    > > > > other reasons). One big advantage of inheritance is, in my opinion, that
    > > > > it enables you to compose more specialized classes from generic ones, it
    > > > > is easy to imagine algebraic ordering relation between types based on
    > > > > inheritance. Your version of statics breaks this assumption without
    > > > > promise of any reward in exchange.

    >
    > > > I don't see how it breaks this relation between classes. Also now it is
    > > > possible to hide supertype's static methods by own implementation. I
    > > > would only add that in some cases this hiding would be required.

    >
    > > I was not very clear, it was late when I was writing :) I guess what
    > > I was trying to say was that you can impose ordering based on
    > > specialization (as opposed to parent-child relationship). Each class
    > > in an inheritance chain either extends or redefines partially its
    > > ancestor (I am using 'or' as logical or). Therefore each class is
    > > either more specialized (if redefinition occurs and it accepts
    > > stronger contract, as in Rectangle->Square) or equally specialized (if
    > > extension occurs and all redefinitions do not change contract - I
    > > treat extension as an interface extension so that class can be used
    > > _additionally_ in different context). Your proposal forces implementor
    > > to provide implementation for non-inheritable method, so it really
    > > can't take any benefit from redefinitions up the chain. Therefore all
    > > concrete classes are at most equally specialized as their context of
    > > usage is determined by a static method. So it does not play well with
    > > most "inheritance patterns". That's how I see it.

    >
    > Now I don't get it. Can you provide an example where you have a class
    > and its specialized subclass and adding an abstract static method to
    > their interface removes/prohibits this specialization?


    Yes, consider
    public abstract class IOStream //for reading disk streams {
    public abstract static boolean isReadable(File f) //returns true
    for files which a concrete class can hopefully process.
    ....
    }

    public class LocalIOStream extends IOstream {
    public static boolean isreadable(File f) { return f.isLocalFile(); }
    ....
    }


    public class AudioVideoStream extends LocalIOStream {
    ???
    }

    in AVStream you have, if I understood you correctly, two choices -
    either to redo all work of super-classes which is not really an
    option, let's say,
    public static boolean isReadable(File f) { return f.isLocalFile() &&
    (f instanceof AudioFile && ((AudioFile)f).getAudioCodecID().equals
    (...);}
    or omit it so then you impose different context. Namely, pretend to be
    able to read remote files while you are not.
    And one more question:
    //client code
    Stream s = new AudioVideStream(..);
    read10Bytes(s);

    public byte[] read10Bytes(Stream s) {
    if (!Stream.isReadable(file)) //how would you dispatch it? There is no
    way I suppose
    }
    Marcin Rze¼nicki, Oct 19, 2009
    #11
  12. Tomas Mikula <> wrote:
    > On Mon, 19 Oct 2009 07:29:24 +0000, Andreas Leitgeb wrote:
    >> Tomas Mikula <> wrote:
    >>> presence of no-arg constructor in a serializable class would be checked
    >>> at compile-time rather than at run-time.

    >> I think this is easily misunderstood. The newly possible compiletime
    >> check would be for compiling the *concrete class* whose name you later
    >> intend to specify dynamically at runtime. This does have some merit.
    >>
    >> Still no compiletime check would of course be possible at the place
    >> where you'd *use* that class dynamically, so nothing at all can be
    >> helped about the reflection-part of this story.

    >
    > The idea here was to automate the reflection.

    Sorry, that is a non-starter.

    If you know the class at compiletime, you can just use it with
    the "new"-operator and have all kinds of compile time checks.

    If you don't know the class at compiletime, then neither does the
    compiler, so there's nothing the compiler could possibly do for you
    beyond what it already does, namely write bytecode to have the JVM
    check it all at runtime.

    Even at runtime, there's no saving: both, interface and existence
    of relevant methods and constructors, each have to be checked
    separately by the JVM.

    I still see some merit in being able to enforce that any concrete
    class implementing some thusly declared interface had to offer some
    particular c'tor, as a means to help developers of such classes to
    not forget about it.


    About the static methods: if you need that kind of enforcement for
    dynamically used classes, then just use instances and non-static
    methods as helpers:

    public interface Foo { // known to the user at compiletime.
    public void pseudoStatic();
    }
    public class FooBar { // known to the user only at runtime
    public void pseudoStatic() { realStatic(); }
    public static void realStatic() { /* do something ... */ }
    }
    // snippet of user's code:
    Foo x = (Foo)use_reflection_to_get_instance(implName); // implName=="FooBar"
    x.pseudoStatic();

    Up to minor syntactical differences this FooBar object does what your
    ".asImplementationOf()" result was intended to do, if I understood it
    correctly. I don't think, that calling static methods on dynamically
    named classes is worth such deep changes as you seem to have in mind
    for this task.
    Andreas Leitgeb, Oct 19, 2009
    #12
  13. On 19 Paź, 16:13, Andreas Leitgeb <>
    wrote:

    >
    > I still see some merit in being able to enforce that any concrete
    > class implementing some thusly declared interface had to offer some
    > particular c'tor, as a means to help developers of such classes to
    > not forget about it.


    Yep, this is not bad.
    Marcin Rze¼nicki, Oct 19, 2009
    #13
  14. Marcin Rzeźnicki wrote:
    > On 19 Paź, 16:13, Andreas Leitgeb <>
    > wrote:
    >
    >> I still see some merit in being able to enforce that any concrete
    >> class implementing some thusly declared interface had to offer some
    >> particular c'tor, as a means to help developers of such classes to
    >> not forget about it.

    >
    > Yep, this is not bad.


    I prefer the annotations-based method such as described here:
    http://www.javaspecialists.eu/archive/Issue167.html

    It works very cleanly - my annotations processors are in a separate JAR
    that I include on the javac classpath. Strictly speaking there's no need
    to specify the processor path if doing this; it will default to the user
    classpath if no processor path is specified. The only change I need to
    make to my "real" source is the actual annotations, like
    @NoArgsConstructor in the example, and quite frankly on the
    implementation classes is where I personally want to enforce a condition
    like this.

    Because of the @Inherited annotation on the @NoArgsConstructor
    annotation it becomes particularly handy. I have found use of this
    approach when a large number of JPA @Entity classes inherit from a
    @MappedSuperclass - it's not uncommon to want to supply some entities
    with useful ctors (and if doing so carelessly the no-args ctor goes
    away); using this kind of annotation on the @MappedSuperclass catches
    all these problems at compile time.

    AHS
    Arved Sandstrom, Oct 19, 2009
    #14
  15. On 19 Paź, 17:32, Arved Sandstrom <> wrote:
    > Marcin Rzeźnicki wrote:
    > > On 19 Paź, 16:13, Andreas Leitgeb <>
    > > wrote:

    >
    > >> I still see some merit in being able to enforce that any concrete
    > >> class implementing some thusly declared interface had to offer some
    > >> particular c'tor, as a means to help developers of such classes to
    > >> not forget about it.

    >
    > > Yep, this is not bad.

    >
    > I prefer the annotations-based method such as described here:http://www.javaspecialists.eu/archive/Issue167.html


    Nice, it wins :)
    Marcin Rzeźnicki, Oct 19, 2009
    #15
  16. Eric Sosman <> wrote:
    > Andreas Leitgeb wrote:
    >> I still see some merit in being able to enforce that any concrete
    >> class implementing some thusly declared interface had to offer some
    >> particular c'tor, as a means to help developers of such classes to
    >> not forget about it.


    > Here's my objection: Suppose there's an Entertainer interface
    > (or abstract class) and ...
    > ...
    > Okay, it might make sense for the class of Comedians to have a
    > default stale Joke (a faithful model of reality, perhaps), ...

    :)
    > ...
    > The author of Entertainer, who knew nothing about the wants and needs
    > of those who would come later, ...


    Thanks for the entertaining example, but I think it's beside the point.
    This type of argument "it's bad for this exemplary usecase, so it must
    be bad for all usecases" is obviously flawed. (or was a joke, itself)

    On second thought: If the Entertainers were designed to be dynamically
    loaded by name, then Comedians just wouldn't have any chance of a individual
    default joke. They could offer their Joke- constructor, but unless they
    also offered a no-args one, they just wouldn't ever be successfully engaged.

    This whole topic is inspired by dynamic loading of classes. Otherwise, there
    wouldn't really be any use for dictating constructors at all. Dynamic loading
    of classes seems to me of increasing importance with all those AppServers,
    J2EE, ... Demanding the default-constructor (or even with a specific set
    of arguments) for those classes imposes no new restriction, just formalizes
    the restrictions that were already imposed by documentation and use.

    PS: In recent threads I spoke up against restrictions, and now I promote them?
    It's different types of restrictions, of course: an extra method or c'tor
    is easily added as a dummy, but an idly added "final" is much harder to come
    by, if deemed improper, later.
    Andreas Leitgeb, Oct 19, 2009
    #16
  17. Marcin Rzeźnicki <> wrote:
    > On 19 Paź, 17:32, Arved Sandstrom <> wrote:
    >> Marcin Rzeźnicki wrote:
    >> > On 19 Paź, 16:13, Andreas Leitgeb <>
    >> > wrote:
    >> >> I still see some merit in being able to enforce that any concrete
    >> >> class implementing some thusly declared interface had to offer some
    >> >> particular c'tor, as a means to help developers of such classes to
    >> >> not forget about it.
    >> > Yep, this is not bad.

    >> I prefer the annotations-based method such as described here:
    >> http://www.javaspecialists.eu/archive/Issue167.html

    > Nice, it wins :)


    Indeed nice, but what would be the extra effort to create e.g. a
    @StringArgConstructor annotation and its processing? And then also
    a @StringStringArgConstructor and a @StringMyFooIntArgConstructor, ...

    As long as this annotation, its processor, and a mechanism to create
    annotations for any particular constructor-signature aren't yet in the
    standard, I wouldn't deem them a full substitute...

    But then again, they do not depend on my deeming it anything... :)
    Andreas Leitgeb, Oct 19, 2009
    #17
  18. Tomas Mikula

    Tomas Mikula Guest

    On Oct 19, 3:51 pm, Marcin Rze¼nicki <>
    wrote:
    > On 19 Pa 1/4, 15:06, Tomas Mikula <> wrote:
    > > I'm saying it is wrong, but just don't like that the implementation
    > > requires a lot of reflection. (I don't mind that implementation of
    > > statndard Java API requires reflection, because someone has already
    > > implemented it for me. But if I want to create my own serialization
    > > framework (e.g. for xml serialization), I need to do a lot of
    > > reflection which could be automated.) Probably one thing I find wrong
    > > with readObject - as I already mentioned, it prevents the object to be
    > > immutable. Though this could also be solved by declaring it static and
    > > use reflection.

    >
    > Yes, but someone did it for you either - JAXB, xStreams etc. This is
    > not a type of work you do day-in day-out, so benefits are rarely to be
    > seen


    Occasionally new frameworks appear. Not an everyday work, but for me
    it justifies the introduction of a new feature, if there is no hidden
    danger we haven't noticed so far. I accept that for you it's not a
    sufficient reason.

    > > > > > Example with generics can easily be substituted by some kind of
    > > > > > "trait" parameter

    >
    > > > > Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    > > > > I would call the zero() method on some instance?
    > > > > Like myDummyVector.zero()?

    >
    > > > I borrowed the terminology from C++. More or less, you add type
    > > > parameter (let's say <Zero extends ZeroVector>) which has a method
    > > > like getZeroVector() (strictly speaking ZeroVector has this method).
    > > > Actual type parameter provides concrete implementation.

    >
    > > I don't see how this would help. Would I call Zero.getZeroVector()?
    > > Probably you meant something else because this leads to the same
    > > problem with calling static method getZeroVector() on a type
    > > parameter. Could you provide an example?

    >
    > OK
    > public class MyVector<T, Zero extends ZeroVector> extends Vector2D<T>
    > {
    > ...
    > public MyVector(Zero zero) { this.zero = zero; }
    > ...
    >
    > }
    >
    > MyVector<Integer, Zero2D> vec = new MyVector(Vector2D.zero());


    OK, but when we already resort to obtaining a zero vector from another
    instance, we don't need a reference to zero stored in each instance of
    vector. We can just have a nonstatic zero() method:

    abstract class Vector<T, V extends Vector<V>> {
    public abstract V zero();
    }

    class Vector2D extends Vector<Integer, Vector2D> {
    public static final Vector2D ZERO = new Vector2D(0, 0);
    public Vector2D zero(){ return ZERO; }
    }

    I wanted to obtain zero without a reference to an instance. Using an
    instance is unnatural and sometimes an instance is just not at hand.

    > > > > > or suitable simple design pattern (for example
    > > > > > Factory), or even with classic sub-typing (zero vector needs not know
    > > > > > its dimension, it can simply 'answer' with neutral element of the ring
    > > > > > on which it is constructed for each and every component query),

    >
    > > > > Allowing operations between a concrete vector and this general zero
    > > > > vector would require to also allow operations between 2D and 3D vetors -
    > > > > the original type safety would disappear.

    >
    > > > I don't get it, could you provide an example?

    >
    > > If I understood well, you meant something like this:

    >
    > > Class Vector {
    > > public static Vector getZeroVector(){
    > > return someSpecialZeroVectorInstance;
    > > }
    > > public abstract Vector add(Vector v);

    >
    > > }

    >
    > > Class Vector2D {
    > > public Vector add(Vector v){...}
    > > ...

    >
    > > }

    >
    > > class MyClass<V extends Vector> {
    > > ...
    > > V v; // V is some concrete class, such as Vector2D
    > > ...
    > > Vector zero = Vector.getZeroVector();
    > > v.add(zero); // adding a general Vector zero to concrete v
    > > // if this is allowed, then also the following is
    > > v.add(new Vector3D(1,2,3)); // summing 2D and 3D vector
    > > ...

    >
    > > }

    >
    > Right but implementation of addition surely checks for this case,
    > doesn't it?


    Not necessarily:

    abstract class Vector<V extends Vector<V>> {
    public V add(V v);
    }

    class Vector2D extends Vector<Vector2D> {
    private final int x, y;
    public Vector2D(int x, int y){ this.x = x; this.y = y; }
    public Vector2D add(Vector2D v){
    return new Vector2D(this.x + v.x, this.y + v.y);
    }
    }

    No checking that the argument of addition has the correct type,
    because this is enforced by the compiler.

    > public void add(Vector<? extends T> v) { if (v.getDimension() !=
    > this.getDimension() ) throw new IllegalArgumentException(); }
    > So it suffices to have a factory method for appropriate zero vectors
    > Vector zero = Vector.getZeroVector(2);
    >
    >
    >
    > > > > > no big
    > > > > > win here either (eliminating type erasure is extremely welcome but for
    > > > > > other reasons). One big advantage of inheritance is, in my opinion, that
    > > > > > it enables you to compose more specialized classes from generic ones, it
    > > > > > is easy to imagine algebraic ordering relation between types based on
    > > > > > inheritance. Your version of statics breaks this assumption without
    > > > > > promise of any reward in exchange.

    >
    > > > > I don't see how it breaks this relation between classes. Also now it is
    > > > > possible to hide supertype's static methods by own implementation. I
    > > > > would only add that in some cases this hiding would be required.

    >
    > > > I was not very clear, it was late when I was writing :) I guess what
    > > > I was trying to say was that you can impose ordering based on
    > > > specialization (as opposed to parent-child relationship). Each class
    > > > in an inheritance chain either extends or redefines partially its
    > > > ancestor (I am using 'or' as logical or). Therefore each class is
    > > > either more specialized (if redefinition occurs and it accepts
    > > > stronger contract, as in Rectangle->Square) or equally specialized (if
    > > > extension occurs and all redefinitions do not change contract - I
    > > > treat extension as an interface extension so that class can be used
    > > > _additionally_ in different context). Your proposal forces implementor
    > > > to provide implementation for non-inheritable method, so it really
    > > > can't take any benefit from redefinitions up the chain. Therefore all
    > > > concrete classes are at most equally specialized as their context of
    > > > usage is determined by a static method. So it does not play well with
    > > > most "inheritance patterns". That's how I see it.

    >
    > > Now I don't get it. Can you provide an example where you have a class
    > > and its specialized subclass and adding an abstract static method to
    > > their interface removes/prohibits this specialization?

    >
    > Yes, consider
    > public abstract class IOStream //for reading disk streams {
    > public abstract static boolean isReadable(File f) //returns true
    > for files which a concrete class can hopefully process.
    > ...
    >
    > }
    >
    > public class LocalIOStream extends IOstream {
    > public static boolean isreadable(File f) { return f.isLocalFile(); }
    > ...
    >
    > }
    >
    > public class AudioVideoStream extends LocalIOStream {
    > ???
    >
    > }
    >
    > in AVStream you have, if I understood you correctly, two choices -
    > either to redo all work of super-classes which is not really an
    > option, let's say,
    > public static boolean isReadable(File f) { return f.isLocalFile() &&
    > (f instanceof AudioFile && ((AudioFile)f).getAudioCodecID().equals
    > (...);}


    You don't have to redo the work, you can call the superclass's static
    method as usual:

    public static boolean isReadable(File f){
    return LocalIOStream.isReadable(f) &&
    f instanceof AudioFile &&
    ((AudioFile)f).getAudioCodecID().equals(...);
    }

    Furthermore, if we expect that specialized IOStreams will only be able
    to process instances specialized instances of File, the IOStreams
    could be parametrized by the type of the File.

    abstract class IOStream<F extends File> {
    public abstract static boolean isReadable(F f);
    }

    class LocalIOStream<F extends File> extends IOStream<F> {
    public static boolean isReadable(F f){
    return f.isLocalFile();
    }
    }

    class AudioVideoStream extends LocalIOStream<AudioFile> {
    public static boolean isReadable(AudioFile f){
    return LocalIOStream.isReadable(f)
    && f.getAudioCodecID().equals(...);
    }
    }

    > or omit it so then you impose different context. Namely, pretend to be
    > able to read remote files while you are not.
    > And one more question:
    > //client code
    > Stream s = new AudioVideStream(..);
    > read10Bytes(s);
    >
    > public byte[] read10Bytes(Stream s) {
    > if (!Stream.isReadable(file)) //how would you dispatch it? There is no
    > way I suppose
    >
    > }


    This would be a compile-time error, since isReadable() is abstract in
    Stream.
    Tomas Mikula, Oct 19, 2009
    #18
  19. Tomas Mikula

    Tomas Mikula Guest

    On Oct 19, 4:13 pm, Andreas Leitgeb <>
    wrote:
    > Tomas Mikula <> wrote:
    > > On Mon, 19 Oct 2009 07:29:24 +0000, Andreas Leitgeb wrote:
    > >> Tomas Mikula <> wrote:
    > >>> presence of no-arg constructor in a serializable class would be checked
    > >>> at compile-time rather than at run-time.
    > >> I think this is easily misunderstood.  The newly possible compiletime
    > >> check would be for compiling the *concrete class* whose name you later
    > >> intend to specify dynamically at runtime. This does have some merit.

    >
    > >> Still no compiletime check would of course be possible at the place
    > >> where you'd *use* that class dynamically, so nothing at all can be
    > >> helped about the reflection-part of this story.

    >
    > > The idea here was to automate the reflection.

    >
    > Sorry, that is a non-starter.
    >
    > If you know the class at compiletime, you can just use it with
    > the "new"-operator and have all kinds of compile time checks.
    >
    > If you don't know the class at compiletime, then neither does the
    > compiler, so there's nothing the compiler could possibly do for you
    > beyond what it already does, namely write bytecode to have the JVM
    > check it all at runtime.


    In my original post I noted that the use of Class's newly introduced
    method
    <T> Implementation<T> asImplementationOf(Class<T> clazz);
    would have the restriction that the type T is known at compile time.
    In this case, the compiler can generate the bytecode to check if the
    'this' class implements T.

    > Even at runtime, there's no saving: both, interface and existence
    > of relevant methods and constructors, each have to be checked
    > separately by the JVM.


    Although my major intention was to reduce writing reflective code,
    there could also be a run-time saving: as soon as the JVM loads a
    class A, it will know if it 'statically implements' interface J. (By
    the same mechanism as it knows if A implements interface I.)
    'Statically implements' would just be a new kind of relationship
    between classes, in addition to 'extends' and 'implements'.

    >
    > I still see some merit in being able to enforce that any concrete
    > class implementing some thusly declared interface had to offer some
    > particular c'tor, as a means to help developers of such classes to
    > not forget about it.
    >
    > About the static methods: if you need that kind of enforcement for
    > dynamically used classes, then just use instances and non-static
    > methods as helpers:
    >
    > public interface Foo {  // known to the user at compiletime.
    >    public void pseudoStatic();}
    >
    > public class FooBar {   // known to the user only at runtime
    >    public void pseudoStatic() { realStatic(); }
    >    public static void realStatic() { /* do something ... */ }}
    >
    > // snippet of user's code:
    > Foo x = (Foo)use_reflection_to_get_instance(implName); // implName=="FooBar"
    > x.pseudoStatic();
    >
    > Up to minor syntactical differences this FooBar object does what your
    > ".asImplementationOf()" result was intended to do, if I understood it
    > correctly.


    Yes, but:
    - it requires to get an unnecessary instance (not so bad yet);
    - getting this instance requires reflection
    - using reflection for getting an instance requires conventions
    which cannot be checked at runtime (such as the presence of
    some particular (e.g. no-arg) constructor)

    If I'm interested in just one static method, it turns out I could just
    use reflection to get this Method instead of a dummy instance.
    Furthermore, if I forget to override pseudoStatic() or realStatic() in
    a subclass, I will get the realStatic() from superclass, which is not
    what I want. The compiler will not enforce me in any way to override
    them.

    > I don't think, that calling static methods on dynamically
    > named classes is worth such deep changes as you seem to have in mind
    > for this task.


    The good thing about it is that the changes are not real changes, just
    extensions. So far I think they are all backward compatible with
    current specification. No old code would be broken if these extensions
    are introduced.
    Tomas Mikula, Oct 19, 2009
    #19
  20. On 19 Pa¼, 19:53, Tomas Mikula <> wrote:
    > On Oct 19, 3:51 pm, Marcin Rze 1/4 nicki <>
    > wrote:
    >
    > > On 19 Pa 1/4, 15:06, Tomas Mikula <> wrote:
    > > > I'm saying it is wrong, but just don't like that the implementation
    > > > requires a lot of reflection. (I don't mind that implementation of
    > > > statndard Java API requires reflection, because someone has already
    > > > implemented it for me. But if I want to create my own serialization
    > > > framework (e.g. for xml serialization), I need to do a lot of
    > > > reflection which could be automated.) Probably one thing I find wrong
    > > > with readObject - as I already mentioned, it prevents the object to be
    > > > immutable. Though this could also be solved by declaring it static and
    > > > use reflection.

    >
    > > Yes, but someone did it for you either - JAXB, xStreams etc. This is
    > > not a type of work you do day-in day-out, so benefits are rarely to be
    > > seen

    >
    > Occasionally new frameworks appear. Not an everyday work, but for me
    > it justifies the introduction of a new feature, if there is no hidden
    > danger we haven't noticed so far. I accept that for you it's not a
    > sufficient reason.
    >


    It is, but I am trying to bring up some dangers of your method
    throughout this thread.

    >
    >
    > > > > > > Example with generics can easily be substituted by some kind of
    > > > > > > "trait" parameter

    >
    > > > > > Sorry, I don't know what you mean by "trait" parameter? Do you mean that
    > > > > > I would call the zero() method on some instance?
    > > > > > Like myDummyVector.zero()?

    >
    > > > > I borrowed the terminology from C++. More or less, you add type
    > > > > parameter (let's say <Zero extends ZeroVector>) which has a method
    > > > > like getZeroVector() (strictly speaking ZeroVector has this method)..
    > > > > Actual type parameter provides concrete implementation.

    >
    > > > I don't see how this would help. Would I call Zero.getZeroVector()?
    > > > Probably you meant something else because this leads to the same
    > > > problem with calling static method getZeroVector() on a type
    > > > parameter. Could you provide an example?

    >
    > > OK
    > > public class MyVector<T, Zero extends ZeroVector> extends Vector2D<T>
    > > {
    > > ...
    > > public MyVector(Zero zero) { this.zero = zero; }
    > > ...

    >
    > > }

    >
    > > MyVector<Integer, Zero2D> vec = new MyVector(Vector2D.zero());

    >
    > OK, but when we already resort to obtaining a zero vector from another
    > instance, we don't need a reference to zero stored in each instance of
    > vector. We can just have a nonstatic zero() method:
    >
    > abstract class Vector<T, V extends Vector<V>> {
    > public abstract V zero();
    >
    > }
    >
    > class Vector2D extends Vector<Integer, Vector2D> {
    > public static final Vector2D ZERO = new Vector2D(0, 0);
    > public Vector2D zero(){ return ZERO; }
    >
    > }
    >
    > I wanted to obtain zero without a reference to an instance. Using an
    > instance is unnatural and sometimes an instance is just not at hand.
    >
    >


    Right, but that was just an example of what is 'trait'. I am not
    saying this is necessarily the best design decision in this case.

    >
    > > Right but implementation of addition surely checks for this case,
    > > doesn't it?

    >
    > Not necessarily:
    >
    > abstract class Vector<V extends Vector<V>> {
    > public V add(V v);
    >
    > }
    >
    > class Vector2D extends Vector<Vector2D> {
    > private final int x, y;
    > public Vector2D(int x, int y){ this.x = x; this.y = y; }
    > public Vector2D add(Vector2D v){
    > return new Vector2D(this.x + v.x, this.y + v.y);
    > }
    >
    > }
    >
    > No checking that the argument of addition has the correct type,
    > because this is enforced by the compiler.
    >
    >


    Formal arguments have to be invariant with respect to overriding in
    Java, you simply created method overload which will be used when
    compiler is sure that runtime type of argument will be Vector2D. You
    will still have to provide 'generic' add method.
    Your example does not help either (or I cannot see how it would)
    because you will not be able to dispatch on v's actual type unless you
    change how invokestatic works.


    >
    > > Yes, consider
    > > public abstract class IOStream //for reading disk streams {
    > > public abstract static boolean isReadable(File f) //returns true
    > > for files which a concrete class can hopefully process.
    > > ...

    >
    > > }

    >
    > > public class LocalIOStream extends IOstream {
    > > public static boolean isreadable(File f) { return f.isLocalFile(); }
    > > ...

    >
    > > }

    >
    > > public class AudioVideoStream extends LocalIOStream {
    > > ???

    >
    > > }

    >
    > > in AVStream you have, if I understood you correctly, two choices -
    > > either to redo all work of super-classes which is not really an
    > > option, let's say,
    > > public static boolean isReadable(File f) { return f.isLocalFile() &&
    > > (f instanceof AudioFile && ((AudioFile)f).getAudioCodecID().equals
    > > (...);}

    >
    > You don't have to redo the work, you can call the superclass's static
    > method as usual:
    >
    > public static boolean isReadable(File f){
    > return LocalIOStream.isReadable(f) &&
    > f instanceof AudioFile &&
    > ((AudioFile)f).getAudioCodecID().equals(...);
    >
    > }


    Yeah, right, but consider what happens when someone implements
    multiple interfaces, or when inheritance tree changes, or when someone
    inherits multiple interfaces with conflicting statics and so on. This
    example is basically hand-crafted implementation of virtual
    dispatch :)

    >
    > Furthermore, if we expect that specialized IOStreams will only be able
    > to process instances specialized instances of File, the IOStreams
    > could be parametrized by the type of the File.
    >
    > abstract class IOStream<F extends File> {
    > public abstract static boolean isReadable(F f);
    >
    > }
    >
    > class LocalIOStream<F extends File> extends IOStream<F> {
    > public static boolean isReadable(F f){
    > return f.isLocalFile();
    > }
    >
    > }
    >
    > class AudioVideoStream extends LocalIOStream<AudioFile> {
    > public static boolean isReadable(AudioFile f){
    > return LocalIOStream.isReadable(f)
    > && f.getAudioCodecID().equals(...);
    > }
    >
    > }


    Well, ok, but it does not change anything. Still you have to re-
    implement invokevirtual by hand all the time :)

    > > or omit it so then you impose different context. Namely, pretend to be
    > > able to read remote files while you are not.
    > > And one more question:
    > > //client code
    > > Stream s = new AudioVideStream(..);
    > > read10Bytes(s);

    >
    > > public byte[] read10Bytes(Stream s) {
    > > if (!Stream.isReadable(file)) //how would you dispatch it? There is no
    > > way I suppose

    >
    > > }

    >
    > This would be a compile-time error, since isReadable() is abstract in
    > Stream.


    This is really bad :) Then actually your statics will be usable only
    when you know exact type you want to work with.
    Marcin Rze¼nicki, Oct 19, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DaKoadMunky
    Replies:
    4
    Views:
    537
    Lee Weiner
    Apr 20, 2004
  2. Icosahedron

    Abstract Static Methods

    Icosahedron, Jan 30, 2004, in forum: C++
    Replies:
    1
    Views:
    362
    Victor Bazarov
    Jan 30, 2004
  3. Iyer, Prasad C

    Abstract Methods & Abstract Class

    Iyer, Prasad C, Oct 20, 2005, in forum: Python
    Replies:
    0
    Views:
    525
    Iyer, Prasad C
    Oct 20, 2005
  4. Gerald Klix

    Re: Abstract Methods & Abstract Class

    Gerald Klix, Oct 20, 2005, in forum: Python
    Replies:
    1
    Views:
    335
    =?iso-8859-1?B?c+liYXN0aWVu?=
    Oct 20, 2005
  5. ankur

    Abstract Static methods

    ankur, Nov 25, 2007, in forum: Java
    Replies:
    5
    Views:
    603
    ankur
    Nov 26, 2007
Loading...

Share This Page