This discussion is archived
2 Replies Latest reply: Sep 7, 2011 5:38 AM by YoungWinston RSS

Enforcing subtype and lower bounds simutanously

882293 Newbie
Currently Being Moderated
Hi out there,

given the two interfaces:
public interface IUnmodField<U, F> {
    F get(F target);
}
and
public interface IField<U,F>
extends IUnmodField<U,F> {

    void set(U source);
}
Is there a way to have a generic method, which
1. sets lower bound constraints for the type of U and V and
2. enforces, that type F is a subclass of U

so that the set() method is valid to be called for U and V.

So, basically, what I want is: (this excerpt does of course not compile):
class Test {
    public static <U extends IUnmodField<U,F>, F extends U & IField<U,F>> void doSomethingCool() {
        
        U u = ... some init;
        F f = .. some init;
        
        f.set(u);
        // f.set(f); // does not work
    }
}
The critical part is
F extends U & IField<U,F>
, but this is not valid Java.

Is there any possibility (maybe by the introduction of some "intermediate" interface) to archieve a solution?

The best I could get is:
class Test {
    public static <U extends IUnmodField<U,F>, F extends IField<U,F>> void doSomethingCool() {
        
        U u = ... some init;
        F f = .. some init;
        
        f.set(u);
        // f.set(f);
    }
}
but this does not enforce F to be a sub-type of U, so set(f) is not possible. (F cannot be converted to U)

Best and many thx in advance

Martin
  • 1. Re: Enforcing subtype and lower bounds simutanously
    jtahlborn Expert
    Currently Being Moderated
    unfortunately, i'm pretty sure what you want to do is not currently possible with java generics.
  • 2. Re: Enforcing subtype and lower bounds simutanously
    YoungWinston Expert
    Currently Being Moderated
    879290 wrote:
    given the two interfaces:
    public interface IUnmodField<U, F> {
    F get(F target);
    }
    and
    public interface IField<U,F>
    extends IUnmodField<U,F> {
    void set(U source);
    }
    Is there a way to have a generic method, which
    1. sets lower bound constraints for the type of U and V and
    2. enforces, that type F is a subclass of U

    so that the set() method is valid to be called for U and V.
    OK, first: Why do you need this? A type, in the above case, is either read-only or writeable, and it doesn't make sense (at least to me) that writable would extend read-only; the two are mutually exclusive.

    Second: What are the types U and V for? You never use them (or at least you could just as easily use F in your IUnmodField interface), so they're just cluttering up the definition.

    If your only concern is not repeating code you could do something like:
    public interface Readable<T extends Readable<T>> {
       public T get();
    }
    
    public interface Writeable<T extends Writeable<T>>
       extends Readable<T>
    {
       public void set(T value);
    }
    
    public abstract class ReadOnly<T extends ReadOnly<T>>
       implements Writeable<T>
    {
       @Override
       public final void set(T value) {
          throw new UnsupportedOperationException();
       }
    }
    or alternatively, define a flag interface called ReadOnly (my preference).

    An interface can only declare intent; it can't prevent idiot developers from adding behaviour they shouldn't, which is why something like "read-only" has to be implemented by a class.

    Winston

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points