Checking Java Collection Generic Type for an Empty Collection

前端 未结 4 1738
情话喂你
情话喂你 2021-01-15 05:56

I want to implement the following function:

public boolean checkType(Vector vec)
{
  // return true if its Vector and false otherwise         


        
4条回答
  •  青春惊慌失措
    2021-01-15 06:36

    Generic type parameters are unrecoverable (except for some special cases) at runtime because of type erasure. This means that at runtime, both Vector and Vector are simply just Vectors and their elements are just Object references.

    Only the actual runtime classes (discoverable by instanceof checks as you pointed out) of the individual elements make the notion of the element type, otherwise the Vector itself has no idea what it's element type is.

    So basically, an empty vector of any type is equal to empty vector of any other type. It is even safe to cast it like this:

    Vector noStrings = (Vector) new Vector();
    

    However there is one problem, because although you can say that empty vector conforms to any required element type, this statement stands only as long as the vector stays empty. Because if you do this:

    Vector ints = new Vector(); // empty
    Vector strings = (Vector) ints; // unchecked warning, but still possibly ok
    ints.add(1); // here comes trouble
    String s = strings.get(1); // oh oh, ClassCastException
    

    EDIT:

    To answer you second question: No it isn't possible to write anything like this:

    public  boolean checkType(Vector vec) {
        return T instanceof Integer; // impossible
        return T == Integer; // impossible
        return T.class == Integer.class // impossible
        return vec instanceof (Vector); // impossible
    }
    

    However you can write a method that uses a class token as an input parameter:

    static  boolean checkElementType(Collection collection, Class elementType) {
        for (Object object : collection) {
            if (!elementType.isAssignableFrom(object.getClass())) {
                return false;
            }
        }
        return true;
    }
    

    And then you can use it like this:

    List list1 = Arrays.asList(1, 2, 3);
    List list2 = Arrays.asList(1, 2, 3, "a");
    System.out.println(checkElementType(list1, Integer.class)); // true
    System.out.println(checkElementType(list2, Integer.class)); // false
    

提交回复
热议问题