Java:通配符类型不匹配导致编译错误 [英] Java: Wildcard Types Mismatch Results in Compilation Error

查看:116
本文介绍了Java:通配符类型不匹配导致编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中创建了一个工厂类,它允许我(理论上)为任何(支持的)给定类型创建管理器。与经理互动让我可以改变给定类型的某些属性。我面临的问题是当我试图为泛型创建一个管理器时,编译器压制了我的希望和梦想。

我正在与之合作。我尝试创建'test3Manager'的行不会编译,我试图理解为什么会出现这种情况。下面的代码显示了一个'解决方法',我试图避免。'

  import java.util.List; 

public class GenTest {
public static void main(String [] args){
String test1 =;
IRandomType< String> test2 = null;
IAnotherRandomType<?> test3 = null;

IManager< String> test1Manager = Factory.createManager(test1);
IManager< IRandomType< String>> test2Manager = Factory.createManager(test2);
IManager< IAnotherRandomType<>> test3Manager = Factory.createManager(test3); //不编译。为什么?

//解决?
IManager<?> test3ManagerTmp = Factory.createManager(test3);
IManager< IAnotherRandomType<>> test3Manager2 =(IManager< IAnotherRandomType<>)test3ManagerTmp;
}

public interface IRandomType< T> {}
public interface IAnotherRandomType< T> {}
public interface IManager< T> {}

public static class Factory {
public static< T> iManager中< T> createManager(T对象){
返回null;



确切的编译错误信息是:

 类型不匹配:无法从GenTest.IManager转换< GenTest.IAnotherRandomType< capture#1-of?>>> GenTest.IManager< GenTest.IAnotherRandomType<>> 

以前有类似的问题(见下文);但是,我不知道这个问题是否被认为是他们的重复。我只是陈述这一点,因为我无法从这些问题推断出我的答案。我希望有人能够澄清我在使用泛型时做了什么错误。



有关SO的相关问题:


  • 有界通配符相关的编译器错误

  • 应该兼容的不兼容通配符类型
  • 使用以下内容:
    $ b

    b $ b

      IManager< IAnotherRandomType<>> test3Manager = 
    Factory。< IAnotherRandomType<>> createManager(test3);

    这只是编译器类型推断的一个例子,所以有必要明确提供类型参数为 T



    更具体地说:

    test3 被声明为 IAnotherRandomType<> ,其中是通配符捕获 - 一种一次性类型参数,代表某种特定的未知类型。这就是编译器在说 capture#1-of?时所指的内容。当您将 test3 传递给 createManager 时, T 会被推断为 IAnotherRandomType< capture#1-of?>


    $ b 同时, test3Manager 被声明为 IManager< IAnotherRandomType<>>> ,它有一个嵌套的通配符 - 它没有表现为类型参数,但表示任何类型



    由于泛型不是协变的,编译器无法从> IManager< ; IAnotherRandomType< capture#1-of?>>< / code>到 IManager< IAnotherRandomType<>>



    更多阅读嵌套通配符:


    I've created a factory class in my project which would allow me (in theory) to create managers for any (supported) given type. Interacting with the manager allows me to alter certain properties of a given type. The problem I'm facing is when I attempt to create a manager for a generic type, the compiler crushes my hopes and dreams.

    The following code is a stripped down version of what I'm working with. The line where I attempt to create my 'test3Manager' will not compile and I'm trying to understand why this is the case. The lines below it shows a 'workaround', which I'm trying to avoid.

        import java.util.List;
    
        public class GenTest {
            public static void main(String[] args) {
                String test1 = "";
                IRandomType<String> test2 = null;
                IAnotherRandomType<?> test3 = null;
    
                IManager<String> test1Manager = Factory.createManager(test1);
                IManager<IRandomType<String>> test2Manager = Factory.createManager(test2);
                IManager<IAnotherRandomType<?>> test3Manager = Factory.createManager(test3); // Doesn't compile. Why?
    
                // Work around?
                IManager<?> test3ManagerTmp = Factory.createManager(test3);
                IManager<IAnotherRandomType<?>> test3Manager2 = (IManager<IAnotherRandomType<?>>) test3ManagerTmp;
            }
    
            public interface IRandomType<T> {}
            public interface IAnotherRandomType<T> {}
            public interface IManager<T> {}
    
            public static class Factory {
                public static <T> IManager<T> createManager(T object) {
                    return null;
                }
            }
        }
    

    The exact compile error message is:

        Type mismatch: cannot convert from GenTest.IManager<GenTest.IAnotherRandomType<capture#1-of ?>> to GenTest.IManager<GenTest.IAnotherRandomType<?>>
    

    Similar questions have been asked before (see below); however, I don't know if this question is considered a duplicate of them. I only state this since I'm having trouble inferring answers from these questions to mine. I'm hoping someone could clarify what I'm doing wrong with my use of generics.

    Related questions on SO are:

    解决方案

    Use the following:

    IManager<IAnotherRandomType<?>> test3Manager =
            Factory.<IAnotherRandomType<?>>createManager(test3);
    

    This is just a case of the compiler's type inference falling on its face, so it's necessary explicitly provide the type argument for T.

    More technically:

    test3 is declared to have the type IAnotherRandomType<?>, where ? is a wildcard capture - a sort of one-use type parameter representing some specific unknown type. That's what the compiler's referring to when it says capture#1-of ?. When you pass test3 into createManager, T gets inferred as IAnotherRandomType<capture#1-of ?>.

    Meanwhile, test3Manager is declared to have the type IManager<IAnotherRandomType<?>>, which has a nested wildcard - it does not behave like a type parameter but rather represents any type.

    Since generics aren't covariant, the compiler can't convert from IManager<IAnotherRandomType<capture#1-of ?>> to IManager<IAnotherRandomType<?>>.

    More reading on nested wildcards:

    这篇关于Java:通配符类型不匹配导致编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆