Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generic type arguments [duplicate]

Tags:

java

generics

I have a method which takes a List<?> as an argument.

public static String method(List<?> arg){
     // Do something based on type of the list
}

//I call the method as below
List<ClassA> listA = new ArrayList<ClassA>();
List<ClassB> listB = new ArrayList<ClassB>();
method(listA);
method(listB);

In method, how do I know if arg is a List of ClassA or a List of ClassB?

like image 716
user682765 Avatar asked Apr 13 '12 22:04

user682765


People also ask

Can a generic class have multiple generic parameters Java?

A Generic class can have muliple type parameters.

How do you add two generic values in Java?

You have to add the numbers as the same type, so you could do x. intValue() + y. intValue(); .

How many type parameters can be used in a generic class?

Multiple parameters You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.

What is generic type arguments?

The generic argument list is a comma-separated list of type arguments. A type argument is the name of an actual concrete type that replaces a corresponding type parameter in the generic parameter clause of a generic type. The result is a specialized version of that generic type.


2 Answers

Technically speaking, you CAN use instanceof to check if an object is a certain type.

However... That's NOT a good idea.

The way you've declared your method, it can accept a List of any type, so it isn't necessarily going to be A or B.

It's hard to tell what you're trying to do, but you probably should make your method generic.

You can do so like this:

public static <T> String method(List<T> arg) {
    // We now know that the type of the list is T, which is
    // determined based on the type of list passed to this
    // method.  This would demonstrate the point better if
    // the return type was T, but I'm leaving the return type
    // as String, because that's what your code returns.
}

Here's a better example:

If you want to create a generic method that returns the first element of a list, you would do it like this:

public static <T> T firstElement(List<T> theList) {
    if (theList == null) {
        return null;
    }
    T objectOfTypeT = theList.get(0);
    return objectOfTypeT;
}

Note that the return type is now T.

Because we made this method generic, it can return the same type that is used in the List.

You would typically just return theList.get(0), but I added a line to make the purpose of generics more obvious.

Explanation of syntax:

  • The <T> indicates that this method takes one type parameter named T.

  • The T that immediately follows is the return type (just like you would normally return String, Integer, etc...).

  • The T in the List parameter is how the compiler knows what the heck a T is.

This allows the compiler to say: "This method expects something of type T. Oh look... The list is also of type T. If somebody passes a list of Strings to this method, than T must be a String. If somebody passes a list of Integers to this method, T must be an Integer."

In contrast, your method can only return a String and it has no idea what type is used in the List.


Also...

If A and B both extend the same class, named TheParentClass, you could declare your method like this:

public static String method(List<? extends TheParentClass> arg)

That way, you'd know a little more about the possible types of your parameter (and can benefit from compile time type checking).

like image 173
jahroy Avatar answered Oct 23 '22 03:10

jahroy


From an answer by the user called Romain " If you use < ?>, you mean you aren't going to use the parametrized type anywhere. Either go to the specific type (in your case it seems List< String>) or to the very generic List< Object> "

Also, I believe that if you use the question mark the compiler wont catch type mismatches until runtime (reified; p.119 of Effective Java), bypassing erasure, and effectively elimating the benefit you get from using generic types???

TO answer the question of the questioner: if you use List< Object> and then try to cast it to A or to B , possibly using instanceOf , that might be a way to tell what it is. I bet there is a better way to do it than that though.

like image 4
djangofan Avatar answered Oct 23 '22 03:10

djangofan