简体   繁体   English

比较Java中的两种泛型类型?

[英]Compare two generic types in Java?

I have the following method: 我有以下方法:

public <U, V> boolean isEqual(List<U> a, List<V> b) {
    // check if U == V
}

I want to check if U and V are the same classes. 我想检查UV是否是相同的类。

You can't do that because of type erasure , it is that simple. 你不能因为类型擦除而这样做,就这么简单。

Consider the following: 考虑以下:

public static void main(String[] args) {
    List<? extends Number> l1 = Arrays.asList(1L, 2, 3L);
    List<? extends Number> l2 = Arrays.asList(1);
    isEqual(l1, l2);
}

public static <U, V> boolean isEqual(List<U> a, List<V> b) {
    // is U == V here?
}

Is U == V here? 这是U == V吗? l1 contains Long and Integer instances but l2 contains a single Integer instance. l1包含LongInteger实例,但l2包含单个Integer实例。


I'm guessing from your comment: 我猜你的评论:

The first condition should be that their type are the same 第一个条件应该是它们的类型是相同的

that what you should have instead is a single type U . 你应该拥有的是单一类型U In this case, use the following signature: 在这种情况下,请使用以下签名:

public static <U> boolean isEqual(List<U> a, List<U> b) {

}

and with that, the above code won't compile anymore. 并且,上面的代码将不再编译。


What you could also do is add 2 parameters accepting the classes: 您还可以做的是添加2个接受类的参数:

public static <U, V> boolean isEqual(List<U> a, List<V> b, Class<U> uClass, Class<V> vClass) {
    if (!uClass.equals(vClass)) {
        // classes are different
    }
}

In this case, you can print a message if the classes given are not the same. 在这种情况下,如果给出的类不相同,则可以打印消息。

If you are making your own class you can require that Class<T> be included in the constructor as demonstrated here 如果您正在制作自己的类可以要求Class<T>包含在构造函数证明这里

Ex: 例如:

public class SomeClass<T> {

    private final Class<T> clazz;

    public SomeClass(Class<T> clazz) {
        this.clazz = clazz;
    }

    public Class<T> getParam() {
        return clazz;
    }
}

Now you can call SomeClass#getParam() to get the type param declared. 现在,您可以调用SomeClass#getParam()来获取声明的类型参数。


There is also a way to do this with reflection. 还有一种方法可以用反射来做到这一点。


All this said, the reason you have to do weird work-arounds to this is because of Type Erasure . 所有这些都说,你必须做一些奇怪的解决方法是因为Type Erasure Basically at runtime Java sees all generics as Object , so while compiling your List may be a List<Integer> or List<Boolean> , but at runtime they're both List<Object> . 基本上在运行时,Java将所有泛型视为Object ,因此编译List可能是List<Integer>List<Boolean> ,但在运行时它们都是List<Object>

If you're trying to compare the contents of two lists, then you shouldn't implement the type comparison yourself. 如果您尝试比较两个列表的内容,则不应自行实现类型比较。 Instead you should do this: 相反,你应该这样做:

    public static <U, V> boolean isEqual(List<U> a, List<V> b) {
        if (a.size() != b.size()) 
            return false;
        for (int i = 0; i < a.size(); i++)
            if (!a.get(i).equals(b.get(i)))
                return false;
        return true;
    }

This way you're relying on the types U and V to be able to handle equals() properly. 这样你就可以依赖类型U和V来正确处理equals()。 Here's some guidelines on implementing equals(): http://www.javaworld.com/article/2072762/java-app-dev/object-equality.html 以下是实现equals()的一些指导原则: http//www.javaworld.com/article/2072762/java-app-dev/object-equality.html

What I'm guessing you want to do is to be able to return quickly in case the types are different. 我猜你想要做的是能够在类型不同的情况下快速返回。 But with implementation I gave you, you'll get the same behaviour -- you'll return on the first iteration. 但是通过我给你的实现,你会得到相同的行为 - 你会在第一次迭代时返回。

Do not rely on 不要依赖

a.getClass().equals(b.getClass())

This is not correct, it will only check whether both are of type ArrayList and not String, Integer etc. 这是不正确的,它只会检查两者是否为ArrayList类型而不是String,Integer等。

Try this only 试试这个

a.get(0).getClass().equals(b.get(0).getClass())

Make sure you check null condition, otherwise you will encounter NullPointerException here. 确保检查null条件,否则在这里会遇到NullPointerException。

我想你想检查a == b而不是U == V.在这种情况下,你必须编写自己的比较方法来比较U和V类的实例。

Assuming a and b are not null and not empty, 假设a和b不为null且不为空,

a.get(0).getClass().equals(b.get(0).getClass())

should do the trick. 应该做的伎俩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM