Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java wild card BestPractices for casting

I have researched this extensively and cant seem to find a best practice for this scenario.

ArrayList<GenericObject<?>> list = new ArrayList<>();
list.add( new GenericObject<Integer>(6) ); // Autoboxing
list.add( new GenericObject<String>("HI") );
if(list.get( 0 ).getGenaricValue().getClass() == Integer.class){

        GenericObject<Integer> gi = (GenericObject<Integer>) list.get( 0 );
        System.out.println("Was Integer");
        System.out.println(gi);
    }
}

while this block of code works the cast from GenericObject <?> to GenericObject<Integer> gives an unchecked warning. Now as you can see i have clearly checked the type with my if statement so I am not paranoid about an exception but is there a better way to do this without having to suppress the unchecked warning? Is there a best practice for this scenario? I have read the entire Generics oracle tutorial here and i have read a lot of stackoverflow posts but none that seem to answer this problem. any help would be appreciated thanks.

like image 471
rickmaster Avatar asked Jan 20 '14 17:01

rickmaster


People also ask

Why wildcards are used in generics?

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).

How do you use a wildcard character in Java?

To declare an upper-bounded wildcard, use the wildcard character ('? '), followed by the extends keyword, followed by its upper bound. Implementation: Java.

How do you use generic wildcards?

Guidelines for Wildcards. Upper bound wildcard − If a variable is of in category, use extends keyword with wildcard. Lower bound wildcard − If a variable is of out category, use super keyword with wildcard. Unbounded wildcard − If a variable can be accessed using Object class method then use an unbound wildcard.


1 Answers

No, there's no better way than to suppress the warning, with an explanation:

@SuppressWarnings("unchecked") // this is okay because [insert reasoning]
GenericObject<Integer> gi = (GenericObject<Integer>) list.get( 0 );

Note that this isn't necessarily a good design however - it's best to avoid unchecked casts if possible, if only because they can be hard to justify. For example, what if gi had earlier been typed as a GenericObject<Object> or GenericObject<Number> and just happened to hold an Integer? It might be better to check and cast the value itself:

GenericObject<?> go = list.get(0);
Object obj = go.getGenericValue();
if (obj instanceof Integer) { // or obj.getClass() == Integer.class
     System.out.println("Was Integer");
}
like image 87
Paul Bellora Avatar answered Oct 16 '22 14:10

Paul Bellora