Pass class type as parameter to use in ArrayList?

2019-02-17 12:07发布

I need to write a java method which takes a class (not an object) and then creates an ArrayList with that class as the element of each member in the array. Pseudo-code example:

public void insertData(String className, String fileName) {
      ArrayList<className> newList = new ArrayList<className>();
}

How can I accomplish this in Java?

3条回答
甜甜的少女心
2楼-- · 2019-02-17 12:33

You can use Generic methods

public <T> void insertData(Class<T> clazz, String fileName) {
   List<T> newList = new ArrayList<>();
}

but if you should use this contract insertData(String className, String fileName), you cannot use generics because type of list item cannot be resolved in compile-time by Java.

In this case you can don't use generics at all and use reflection to check type before you put it into list:

public void insertData(String className, String fileName) {
    List newList = new ArrayList();

    Class clazz;
    try {
        clazz = Class.forName(className);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e); // provide proper handling of ClassNotFoundException 
    }

    Object a1 = getSomeObjectFromSomewhere();

    if (clazz.isInstance(a1)) {
        newList.add(a1);
    }
    // some additional code
}

but without information of class you're able use just Object because you cannot cast your object to UnknownClass in your code.

查看更多
Ridiculous、
3楼-- · 2019-02-17 12:38

Vlad Bochenin gives a good way but it makes no sense to provide a T generic that derives from nothing in your method.
It puts zero constraints in the code of insertData() that manipulates the list.
You will be forced to do cast in the code and it defeats the purpose of Generics.

I suppose you want manipulate some instances of known classes in insertData().
And if you use generic in your case, it would have more meaningful if you have subtypes of classes to manipulate.

In this way, you could have a method that accepts a base type and its subclases.

public static <T extends YourClass> void insertData(Class<T> clazz, String fileName) {
    List<T> newList = new ArrayList<>();
    T t = newList.get(0);
    // here I can manipulate something that derives from YourClass
}
查看更多
趁早两清
4楼-- · 2019-02-17 12:44

My guess is that what you really want to do is to return the generated List. This is what that might look like:

public <T> List<T> loadData(Class<T> clazz, String fileName) {
    List<T> newList = new ArrayList<>();

    //...populate list somehow (e.g. with values deserialized from the file named "filename")

    return newList;
}

This is how it could be used:

List<String> names = loadData(String.class, "someFileContainingNameStrings");
List<Double> temperatures = loadData(Double.class, "someFileContainingTemperatureData");
查看更多
登录 后发表回答