0

Following are my classes. in the Test class, I am unable to return object of SubClass I am getting the error

The method method2(SuperClass, Class) in the type GenericClass is not applicable for the arguments (SubClass, Class)

public class GenericClass<T> {

    public T method1(T obj, Class<T> clazz) {
        System.out.println(obj);
        return obj;
    }

    public T method2(T obj, Class<T> clazz) {
        System.out.println(obj);
        return obj;
    }
}

public class Test extends GenericClass<SuperClass> {

    public SuperClass printMethod1() {
        SuperClass sClass = new SuperClass();
        sClass.setName("name");
        sClass.setEmail("email");
        sClass.setAddress("Address");
        return this.method1(sClass, SuperClass.class);
    }

    public SubClass printMethod2() {
        SubClass subClass = new SubClass();
        subClass.setName("testName");
        subClass.setEmail("testEmail");
        subClass.setAddress("testAddress");
        subClass.setName2("name2");
        return this.method2(subClass, SubClass.class);
    }
}

public class SuperClass {

    private String name;
    private String email;
    private String address;

    public String getName() {
        return this.name;
    }
    public void setName(String name_p) {
        this.name = name_p;
    }
    public String getEmail() {
        return this.email;
    }
    public void setEmail(String email_p) {
        this.email = email_p;
    }
    public String getAddress() {
        return this.address;
    }
    public void setAddress(String address_p) {
        this.address = address_p;
    }
}

public class SubClass extends SuperClass {

    private String name2;

    public String getName2() {
        return this.name2;
    }

    public void setName2(String name2_p) {
        this.name2 = name2_p;
    }

}

I need the parameter Class class in the GenericClass for different purpose(I did not put the logic here)

I tried casting but it doesn't work. can you please suggest how can I return SubClass object in printMethod2.

Shiva
  • 913
  • 2
  • 8
  • 7
  • Basically, because `Class` is _not_ a sub-type of `Class` -- see the question I've marked as a duplicate for more info. – yshavit Apr 14 '16 at 20:17
  • @yshavit Wildcards don't work here. I'm tempted to just reopen the question. – Radiodef Apr 14 '16 at 20:19
  • @Radiodef I'm not quite sure I follow you about them not working... but feel free to reopen it if you feel like it's not a dupe. :) (But in that case, I think the question should be edited to explain why it's not a dupe, because it certainly looks like the common "why isn't `Foo` a subtype of `Foo`?" to me) – yshavit Apr 14 '16 at 20:39

1 Answers1

0

Declaring a type variable with a bound should work for you:

public <U extends T> U method2(U obj, Class<U> clazz) {...}

This means that the return type is the same as the type of object you pass to the method.

That is pretty much the only solution because the line

return this.method2(subClass, SubClass.class);

shows that you want the method to also return the same type that you pass it.


edit:

The full class for your example code will look something like this:

public class GenericClass<T> {

    public T method1(T obj, Class<T> clazz) {
        System.out.println(obj);
        return obj;
    }

    public <U extends T> U method2(U obj, Class<U> clazz) {
        System.out.println(obj);
        return obj;
    }
}

(Here's the example compiling on Ideone: http://ideone.com/SRlIfo.)

Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • You don't need to change anything except the method to use this. If you can't change the method, then there's no solution. This is the only way to e.g. also return `SubClass` from the method. The only reason this wouldn't work is if there is a situation where you e.g. *pass* a `SuperClass` to `method2` and *return* a `SubClass`. – Radiodef Apr 14 '16 at 20:50