繁体   English   中英

Java泛型-带有可选包装泛型的意外情况

[英]Java generics - unexpected situation with Optional wrapping generics

我已经遇到以下情况:

import com.google.common.base.Optional;

public class CovarianceTest {

    class Race {
    }

    class Dog<Race> {
    }

    public Optional<Dog<? extends Race>> getDog() {
        Dog<? extends Race> dogWithSomeRace = new Dog();
        return Optional.of(dogWithSomeRace);
    }
}

这样的情况会导致编译问题。 IDE说:

Incompatible types.
Required: Optional<Dog<? extends Race>>
Found: Optional<? extends Dog<? extends Race>

这显然是错误的。

有人可以解释为什么会这样吗?

似乎您将类的泛型类型声明与泛型类型参数的边界声明混淆了。

在您的情况下:

class Race {}

class Dog<Race> {} // "Race" is declared as a generic type in dog. It's not referring to your Race class in any way.

您对Dog定义等同于

class Dog<E> {}

如果要将Race的子类设置为Dog的通用边界,请执行例如

class Dog<E extends Race> {}

您还可以优化方法的泛型声明:

public Optional<Dog<? extends Race>> // this could be shortend to Dog<?>, because Dog's boundary is already limited to Race in the class signature
                                     getDog() {
    Dog<? extends Race> dogWithSomeRace // This can be shortend aswell to Dog<?> 
                                        = new Dog(); // Missing type declaration in the constructor call 
    return Optional.of(dogWithSomeRace);
}

这是您的代码:

  1. 编译器认为Race (在Dog<Race>类中)是一个类型参数,将用于进一步对class Dog进行参数化。
  2. 在作业Dog<? extends Race> dogWithSomeRace = new Dog(); Dog<? extends Race> dogWithSomeRace = new Dog(); 这被认为不是最佳实践。

在此处输入图片说明

我相信下面的代码就是您要尝试执行的操作。 使用T作为类型参数。 开始了:

import com.google.common.base.Optional;

public class CovarianceTest {

    class Race {
    }

    class Dog<T> {
        void whatever(T t) {
            System.out.println(t);
        }
    }

    public Optional<Dog<? extends Race>> getDog() {
        Dog<? extends Race> dogWithSomeRace = new Dog<Race>();
        return Optional.of(dogWithSomeRace);
    }

    public static void main(String[] args) {
        System.out.println((new CovarianceTest()).getDog().isPresent());
        System.out.println((new CovarianceTest()).getDog().get().getClass());
    }
}

打印效果很好:

真正
类CovarianceTest $ Dog

暂无
暂无

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

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