如何初始化作为参数接收的 class 类型的列表?
How to initialize a list of a class type received as a parameter?
我是 Java 的初学者。
如何初始化作为参数接收的 class 类型的列表?我有一个方法将 Class<?>
参数作为参数,我想创建一个 class 类型的列表。
public List<?> returnList(Class<?> listItemType) {
//create a list of type "listItemType"
//populate the list
//return the list
}
我试过
List<listItemType> list = new ArrayList<listItemType>()
但 VSCode 显示 listItemType cannot be resolved to a type
。
我也试过<? extends listItemType>
、<listItemType.getName()>
和下面的代码,但它们似乎也不起作用。
Object obj = listItemType.getDeclaredConstructor().newInstance();
List<obj.getClass()> = new ArrayList<obj.getClass()>();
你需要的是 generic method.
Generic methods allow type parameters to be used to express
dependencies among the types of one or more arguments to a method
and/or its return type.
这是一个完整的例子:
public class NewMain {
private static class Foo {
public Foo() {
}
}
public static void main(String[] args) {
// TODO code application logic here
List<Foo> foos = returnList(Foo.class);
System.out.println(foos.get(0));
}
public static <T> List<T> returnList(Class<T> listItemType) {
List<T> list = new ArrayList<>();
try {
T obj = listItemType.getConstructor().newInstance();
list.add(obj);
} catch (Exception ex) {
Logger.getLogger(NewMain.class.getName()).log(Level.SEVERE, null, ex);
}
return list;
}
}
如果您使该方法成为具有命名类型参数的泛型方法,它将起作用。例如:
public <T> List<T> returnList(Class<T> listItemType) {
List<T> list = new ArrayList<>();
try {
list.add(listItemType.getConstructor().newInstance());
} catch (ReflectiveOperationException ex) {
// do something
}
return list;
}
请注意,可能存在各种例外情况。例如,class 可能没有合适的构造函数,构造函数可能无法访问,或者它可能会抛出异常。此方法的完整版本应该做一些适当的事情,或者声明相关的异常,以便它们可以传播给调用者和其他人。
如果没有 named 类型参数 T
,您不会将 List<?>
中的通配符连接到 Class<?>
中的通配符。所以编译器不会知道 returnList(Foobar.class)
的目的是 return a List<Foobar>
.
并且无法像 List<listItemType>
中那样将变量名称 listItemType
用作 class 名称。这就是为什么您得到“listItemType 无法解析为类型”的原因。变量名称和类型名称位于不同的 Java 命名空间中。
您的尝试 <? extends listItemType>
因同样的原因而失败,并且
<listItemType.getName()>
失败,因为表达式不是类型。
考虑这些失败尝试的另一种方式是它们使用运行时值(例如 listItemType
的值)进行编译时类型检查。这意味着编译器需要能够展望未来,以了解运行时值 将 是什么。千里眼不是当前一代 Java 编译器的功能:-)。
我是 Java 的初学者。
如何初始化作为参数接收的 class 类型的列表?我有一个方法将 Class<?>
参数作为参数,我想创建一个 class 类型的列表。
public List<?> returnList(Class<?> listItemType) {
//create a list of type "listItemType"
//populate the list
//return the list
}
我试过
List<listItemType> list = new ArrayList<listItemType>()
但 VSCode 显示 listItemType cannot be resolved to a type
。
我也试过<? extends listItemType>
、<listItemType.getName()>
和下面的代码,但它们似乎也不起作用。
Object obj = listItemType.getDeclaredConstructor().newInstance();
List<obj.getClass()> = new ArrayList<obj.getClass()>();
你需要的是 generic method.
Generic methods allow type parameters to be used to express dependencies among the types of one or more arguments to a method and/or its return type.
这是一个完整的例子:
public class NewMain {
private static class Foo {
public Foo() {
}
}
public static void main(String[] args) {
// TODO code application logic here
List<Foo> foos = returnList(Foo.class);
System.out.println(foos.get(0));
}
public static <T> List<T> returnList(Class<T> listItemType) {
List<T> list = new ArrayList<>();
try {
T obj = listItemType.getConstructor().newInstance();
list.add(obj);
} catch (Exception ex) {
Logger.getLogger(NewMain.class.getName()).log(Level.SEVERE, null, ex);
}
return list;
}
}
如果您使该方法成为具有命名类型参数的泛型方法,它将起作用。例如:
public <T> List<T> returnList(Class<T> listItemType) {
List<T> list = new ArrayList<>();
try {
list.add(listItemType.getConstructor().newInstance());
} catch (ReflectiveOperationException ex) {
// do something
}
return list;
}
请注意,可能存在各种例外情况。例如,class 可能没有合适的构造函数,构造函数可能无法访问,或者它可能会抛出异常。此方法的完整版本应该做一些适当的事情,或者声明相关的异常,以便它们可以传播给调用者和其他人。
如果没有 named 类型参数 T
,您不会将 List<?>
中的通配符连接到 Class<?>
中的通配符。所以编译器不会知道 returnList(Foobar.class)
的目的是 return a List<Foobar>
.
并且无法像 List<listItemType>
中那样将变量名称 listItemType
用作 class 名称。这就是为什么您得到“listItemType 无法解析为类型”的原因。变量名称和类型名称位于不同的 Java 命名空间中。
您的尝试 <? extends listItemType>
因同样的原因而失败,并且
<listItemType.getName()>
失败,因为表达式不是类型。
考虑这些失败尝试的另一种方式是它们使用运行时值(例如 listItemType
的值)进行编译时类型检查。这意味着编译器需要能够展望未来,以了解运行时值 将 是什么。千里眼不是当前一代 Java 编译器的功能:-)。