简体   繁体   English

Java Generics 不兼容类型为完全相同的 class

[英]Java Generics incompatible types for the exact same class

Here is an example of my Java code:这是我的 Java 代码示例:

package com.company;

public class Main {

    private static class Something<T>{
        public void fun(Class<T> someClass){
            someClass.cast(null);
        }
    }
    private interface Hello{}

    public static void some(Something<? extends Hello> mySomething, Class<? extends Hello> myClass){
        mySomething.fun(myClass);
    }
}

And I'm getting a weird error at the mySomething.fun(myClass) line:我在mySomething.fun(myClass)行遇到了一个奇怪的错误:

Required type: Class<? extends com.company.Main.Hello>
Provided: Class<? extends com.company.Main.Hello>

Which are the exact same type...哪些是完全相同的类型...

What am I missing here?我在这里想念什么?

I believe the problem is that the question mark in the "required" and "provided" can be different.我认为问题在于“必需”和“提供”中的问号可能不同。 Suppose I have two implementations of Hello : Hello1 and Hello2 .假设我有Hello的两个实现: Hello1Hello2 I could call:我可以打电话:

some(new Something<Hello2>(), Hello1.class);

That fulfills the contract of some , but you don't want to be able to call new Something<Hello2>().someClass(Hello1.class) .这满足了some的合同,但您不希望能够调用new Something<Hello2>().someClass(Hello1.class)

I believe you need to express the constraint once , by making some generic:我相信你需要通过做some通用来表达约束

public static <T extends Hello> void some(Something<T> mySomething, Class<T> myClass)

Now the two parameters are appropriately related, so the call to fun is valid.现在这两个参数是适当相关的,所以对fun的调用是有效的。

Class<? extends com.company.Main.Hello> Class<? extends com.company.Main.Hello> is a Class whose type parameter is Hello or some class that extends Hello . Class<? extends com.company.Main.Hello>是一个Class ,其类型参数是Hello或扩展Hello的一些 class 。

Therefore two unrelated Class<? extends com.company.Main.Hello>因此两个不相关Class<? extends com.company.Main.Hello> Class<? extends com.company.Main.Hello> might represent two different sub-classes of Hello . Class<? extends com.company.Main.Hello>可能代表Hello的两个不同子类。

For example, suppose you passed to your some(Something<? extends Hello> mySomething, Class<? extends Hello> myClass) method a Something<Hello1> and a Class<Hello2> .例如,假设您向您的some(Something<? extends Hello> mySomething, Class<? extends Hello> myClass)方法传递了Something<Hello1>Class<Hello2> Both Hello1 and Hello2 are sub-classes of Hello , but you can't pass a Class<Hello2> argument to the fun() method of Something<Hello1> (which requires a Class<Hello1> ). Hello1Hello2都是Hello的子类,但您不能将Class<Hello2>参数传递给Something<Hello1>fun()方法(这需要Class<Hello1> )。

<? extends MyClass> <? extends MyClass> (in the first parameter) is not guaranteed to be the compatible to <? extends MyClass> <? extends MyClass> (在第一个参数中)不保证与<? extends MyClass> <? extends MyClass> (in the second parameter). <? extends MyClass> (在第二个参数中)。

If the types were the same, for example:如果类型相同,例如:

public static <T> void some(Something<T> mySomething, Class<T> myClass) {
    mySomething.fun(myClass);
}

then compilation passes just fine.然后编译通过就好了。

You need to change your some() definition to:您需要将some()定义更改为:

public static <T extends Hello> void some(Something<T> mySomething, Class<T> myClass) {
    mySomething.fun(myClass);
}

This is because in your Something class, the type T is used in the fun declaration in a way that the actual type of T must exactly be the same.这是因为在您的Something class 中,类型Tfun声明中使用的方式是T的实际类型必须完全相同。

But in your some method, ? extends Hello但是在你的some方法中, ? extends Hello ? extends Hello can be different classes. ? extends Hello可以是不同的类。 Hello can have multiple child classes. Hello可以有多个子类。

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

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