如何将泛型类传递给 Java 中的方法?

发布于 2024-11-01 20:44:19 字数 549 浏览 1 评论 0原文

假设我们有一个函数,可以创建给定特定类的对象:

public static <T> T createObject(Class<T> generic) {
    try {
        return generic.newInstance();
    } catch (Exception ex) {
        return null;
    }
}

我们可以轻松地使用该函数来创建非泛型类型的实例。

public static void main(String[] args) {
    Foo x = createObject(Foo.class);
}

是否可以用泛型类型做同样的事情?

public static void main(String[] args) {
    ArrayList<Foo> x = createObject(ArrayList<Foo>.class); // compiler error
}

Suppose we have a function that creates objects given a particular class:

public static <T> T createObject(Class<T> generic) {
    try {
        return generic.newInstance();
    } catch (Exception ex) {
        return null;
    }
}

We can use the function easily to create instances of non-generic types.

public static void main(String[] args) {
    Foo x = createObject(Foo.class);
}

Is it possible to do the same thing with a generic type?

public static void main(String[] args) {
    ArrayList<Foo> x = createObject(ArrayList<Foo>.class); // compiler error
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我恋#小黄人 2024-11-08 20:44:19

Java 中的泛型是通过类型擦除来实现的。

这意味着 ArrayList 在运行时是一个 ArrayList。编译器只是为您插入强制转换。

您可以使用以下方法进行测试:

ArrayList<Integer> first = new ArrayList<Integer>();
ArrayList<Float> second = new ArrayList<Float>();

if(first.getClass() == second.getClass())
{
    // should step in the if
}

Generics, in Java, are implemented through type erasure.

That means that an ArrayList<T>, at run time, is an ArrayList. The compiler simply inserts casts for you.

You can test this with the following:

ArrayList<Integer> first = new ArrayList<Integer>();
ArrayList<Float> second = new ArrayList<Float>();

if(first.getClass() == second.getClass())
{
    // should step in the if
}
守不住的情 2024-11-08 20:44:19

另外,只要您确定自己在做什么,并且非常确定您的代码不会引起堆污染,您就可以抑制警告。

您还可以考虑到您的代码无法实例化数组,这偶然也需要一个未经检查的异常:

@SuppressWarnings("unchecked")
public static <T> T[] createArray(Class<T> anyClass, int size){
    T[]result = null;
    try{
        result = (T[]) Array.newInstance(anyClass, size);
    }catch(Exception e){
        e.printStackTrace();
    }
    return result;
}

这就是我使用它的方式:

public static void main(String[] args) throws Exception{
    @SuppressWarnings("unchecked")
    List<String> jediNames = (List<String>) createObject(ArrayList.class);
    jediNames.add("Obiwan");

    String[] moreJedis = createArray(String.class, 10);
    System.out.println(moreJedis.length);
    moreJedis[0] = "Anakin";
}

Also, as long as you are sure of what you are doing, and as long as you are pretty sure your code cannot incur heap pollution you can suppress the warning.

You may also take into consideration that your code cannot instantiate arrays, which by chance also requires an unchecked exception:

@SuppressWarnings("unchecked")
public static <T> T[] createArray(Class<T> anyClass, int size){
    T[]result = null;
    try{
        result = (T[]) Array.newInstance(anyClass, size);
    }catch(Exception e){
        e.printStackTrace();
    }
    return result;
}

This is how I used it:

public static void main(String[] args) throws Exception{
    @SuppressWarnings("unchecked")
    List<String> jediNames = (List<String>) createObject(ArrayList.class);
    jediNames.add("Obiwan");

    String[] moreJedis = createArray(String.class, 10);
    System.out.println(moreJedis.length);
    moreJedis[0] = "Anakin";
}
请止步禁区 2024-11-08 20:44:19

如果您确实需要,您可以强制它进行编译,而不会出现错误或警告:

@SuppressWarnings("unchecked")
ArrayList<Foo> x = (ArrayList<Foo>) createObject(ArrayList.class);

唯一的问题是在编译时它不能保证 createObject() 不会将对象添加到您的 不是 Foo 类型的 ArrayList。这对于您的情况可能是安全的,因此您仍然可以获得泛型的好处,而无需求助于使用 ArrayList

If you really need to you can force it to compile without errors or warnings:

@SuppressWarnings("unchecked")
ArrayList<Foo> x = (ArrayList<Foo>) createObject(ArrayList.class);

The only trouble is that at compile time it can't guarantee that createObject() isn't adding objects to your ArrayList that aren't of type Foo. That's probably safe in your case, so you'll still get the benefit of generics without resorting to using ArrayList<?>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文