Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform a checked cast?

I am new to Generics and am having an issue.

Consider the following code:

public class A {}
public class B extends A {}

public <T extends A> T getB()
{
    A test = new B();
    Class<B> clazz = B.class;
    if (clazz.isInstance(test))
    {
        return (T)test;
    }
    return null;
}

This generates an Unchecked cast warning. on the return (T)test; line. but clearly I am checking the type with the if (clazz.isInstance(test)) line.

Is there a way to do a "checked cast"?

I'm not looking to just suppress the warning but actually implement a checked cast. Unfortunately I can't find information on how to perform a checked cast.

like image 835
AllenKll Avatar asked Sep 24 '14 16:09

AllenKll


People also ask

What does unchecked cast mean?

2. What Does the “unchecked cast” Warning Mean? The “unchecked cast” is a compile-time warning. Simply put, we'll see this warning when casting a raw type to a parameterized type without type checking. An example can explain it straightforwardly.

How do I fix an unchecked cast warning?

You're using a raw type in your code, which is giving you the unchecked cast problem. You normally fix this by using a fully parameterized class instead: Comparable<Whatever>.

Can you cast a superclass to a subclass?

You can always successfully cast a superclass to a subclass. An interface can be a separate unit and can be compiled into a bytecode file. The order in which modifiers appear before a class or a method is important. Every class has a toString() method and an equals() method.


1 Answers

Is there a way to do a "checked cast"?

Sure, although it's important to note that it doesn't really help you here, because your method is hard-coded to use B in a few places. You can perform the cast with:

clazz.cast(test)

... but that will cast to B, not T. In particular, suppose I ran:

public class C extends A {}

...

C c = foo.<C>getB();

How would you expect that to work?

You might want to change your code to something like:

public <T extends A> T getB(Class<T> clazz)
{
    A test = // get A from somewhere
    return clazz.isInstance(test) ? clazz.cast(test) : null;
}

Then that's fine, because clazz.cast will return a value of type T, which you're fine to return.

like image 82
Jon Skeet Avatar answered Sep 20 '22 12:09

Jon Skeet