Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Compile error when return Generic Class type

public interface Parent{
}

public class Child implements Parent{
}

public <T extends Parent> Class<T> getClass(){
  return Child.class;  // compile error, add cast to Class<T>
}

I expect there is no error about above code, however I get compile error when I return Child.class.

like image 499
user2201253 Avatar asked Jan 29 '16 08:01

user2201253


People also ask

Do generics prevent compile time errors?

Type Safety: Generics make errors to appear compile time than at run time (It's always better to know problems in your code at compile time rather than making your code fail at run time).

Do generics prevent type cast errors?

Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.

Do generics exist after compilation?

Some generics stay in the compiled class -- specifically including method signatures and class definitions, for example. At runtime, no objects keep their full generic type, but even at runtime you can look up the generic definition of a class or a method.

Can you cast to a generic type Java?

The Java compiler won't let you cast a generic type across its type parameters because the target type, in general, is neither a subtype nor a supertype.


2 Answers

You can't tell Java to always return Child.class regardless of T. There might be other classes extending from parent that aren't a Child. Also, since you are not using T anywhere, your code doesn't make much sense. Two possible solutions:

public Class<? extends Parent> getAClass() {
    return Child.class;
}

or perhaps

public <T extends Parent> Class<T> getAClass(Class<T> clazz){
    return clazz; 
}

The second example compiles, but would probably make more sense if T was declared at class level.

Also, I renamed your method to avoid a name clash with the existing getClass() method.

like image 147
Keppil Avatar answered Oct 27 '22 10:10

Keppil


Review the following

public class Main {
    public interface Parent{}
    public class Child implements Parent{}        
    public class BadChild implements Parent {}

    public static <T extends Parent> Class<T> getClazz() {
        return Child.class;  // compile error, add cast to Class<T>
    }

    public static void main(String[] args) {
        Class<BadChild> clazz = Main.<BadChild>getClazz();
    }
}

Calling method getClazz() with BadChild type is valid for the caller side. If you could compile your method that would lead to runtime errors. That's why this is forbidden.

like image 41
AdamSkywalker Avatar answered Oct 27 '22 10:10

AdamSkywalker