Reading Type From UpperBound

Java-Reading Type From UpperBound

Reading Type From UpperBound

We have to take the two cases separately. Drawing on the analogy of a container, we’ll call getting a return value from a method on an object as a specific type reading the object as a type. Conversely, we’ll call passing arguments of a specific type to methods of the object writing the object as a type. So, for example :

Reading Type From UpperBound

A Gen<A> can be read and written as the A type and a Gen<B> can be read and written as the B type. To be more precise, though, we should say that Gen<A> can be read as the A type, but can be written as any subtype of A. After all, we could add a B or C to a Gen<A> :

Reading Type From UpperBound

Let’s look now at the wildcard instantiation Gen<? extends A>. We know it holds an instantiation of the Gen type on some type of A. What more can we say about the elements of such a Gen, which could hold any instantiation of the A type? Well, the elements will always be subtypes of A(B and C). This means that at a minimum, we should be able to read the object through our wildcard type as type A :

Reading Type From UpperBound

The compiler lets us assign the value directly to a ‘A’ because it knows that whatever the instantiation of the Gen, the elements must be a subtype of ‘A’. Of course, we could have read the object as type Object if we’d wanted to as well. But what about going the other way and writing? If genA could be an instantiation of Gen on any subclass of ‘A’, how can we know what type of objects to write to it? The answer is that we can’t. Since we don’t know the correct type, the compiler won’t let us write anything to the Gen through our wildcard instantiation of the type :

Reading Type From UpperBound

Another way to put this is that because our wildcard instantiation has an upper bound of A, we can only read the type as A. We’ll reiterate that in the form of a rule in a moment.

Program

Reading Type From UpperBound Private-Interface-Methodss2

Program Source

class A {

    int a;

    A(int aa) {
        a = aa;
    }
}
class B extends A {

    int b;

    B(int aa, int bb) {
        super(aa);
        b = bb;
    }
}
class C extends B {

    int c;

    C(int aa, int bb, int cc) {
        super(aa, bb);
        c = cc;
    }
}
class Gen<T> {

    T t[];

    Gen(T tt[]) {
        t = tt;
    }
    T getSpecifiedType(int i){
        return t[i];
    }
}
public class Javaapp {

    static void showBC(Gen<? extends B> ge) {
        
        System.out.println(".........showBC.........");
        
        for(B b : ge.t){
            
            System.out.println("a-> : " + b.a + " b-> : " + b.b);
        }
    }

    static void showC(Gen<? extends C> ge) {
        
        System.out.println(".........showC........");
        
        for(C c : ge.t){
            
            System.out.println("a-> : " + c.a + " b-> : " + c.b + " c-> : " + c.c);
        }
    }

    public static void main(String[] args) {

        Gen<B> genB = new Gen<B>(new B[]{new B(2,4), new B(6,8), new C(12,14,16)});
        Gen<C> genC = new Gen<C>(new C[]{new C(10,20,30), new C(40,50,60), new C(70,80,90)});
        showBC(genB);
        showBC(genC);
        showC(genC);  
    }
}

Leave a Comment