2 Replies Latest reply: Sep 7, 2011 7:38 AM by YoungWinston RSS

    Enforcing subtype and lower bounds simutanously

    882293
      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
          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
            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