相关疑难解决方法(0)

List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的?

我对Java泛型如何处理继承/多态性感到困惑.

假设以下层次结构 -

动物(父母)

- (儿童)

所以假设我有一个方法doSomething(List<Animal> animals).根据所有继承和多态的规则,我会假设a List<Dog> a List<Animal>而a List<Cat> a List<Animal>- 所以任何一个都可以传递给这个方法.不是这样.如果我想实现这种行为,我必须明确告诉该方法接受一个Animal的任何子类的列表doSomething(List<? extends Animal> animals).

我知道这是Java的行为.我的问题是为什么?为什么多态通常是隐含的,但是当涉及泛型时必须指定它?

java generics polymorphism inheritance

727
推荐指数
10
解决办法
10万
查看次数

144
推荐指数
5
解决办法
3万
查看次数

在Java中展示协方差和逆变?

请给出Java中协方差和逆变的一个很好的例子.

java covariance contravariance

100
推荐指数
2
解决办法
4万
查看次数

Java将java.lang.Object列表中的特定类列表添加到java 8流中 - 为什么?

public class Test {

    static List<Object> listA = new ArrayList<>();

    public static void main(final String[] args) {
        final List<TestClass> listB = new ArrayList<>();
        listB.add(new TestClass());

        // not working
        setListA(listB);

        // working
        setListA(listB.stream().collect(Collectors.toList()));

        System.out.println();
    }

    private static void setListA(final List<Object> list) {
        listA = list;
    }

}
Run Code Online (Sandbox Code Playgroud)

为什么它适用于流,并不适用于简单的集合?

java generics inheritance java-8 java-stream

8
推荐指数
1
解决办法
162
查看次数

Java 8不兼容的类型错误

Set<Object> removedObjs = new HashSet<>();
List<? extends MyEntity> delObjs = (List<? extends MyEntity>) new ArrayList<>(removedObjs);
Run Code Online (Sandbox Code Playgroud)

MyEntity 是标记界面.

上面的代码在(java版本"1.7.0_91",准确)中工作正常,但在(java版本"1.8.0_77")中没有

在Java8中,我收到以下异常:

incompatible types: ArrayList<Object> cannot be converted to List< ? extends MyEntity>

java java-7 java-8

7
推荐指数
2
解决办法
1826
查看次数

Java中的不变性,协方差和逆变性

关于泛型的 Java 课程正在引导我出现方差概念.这让我有些头疼,因为我无法找到它的简单演示.

我已经在stackoverflow上阅读了几个类似的问题,但我发现它们对于Java学习者来说太难理解了.实际上问题在于对泛型的解释需要理解方差,并且证明了方差的概念在很大程度上依赖于泛型理解.

我有一些希望读到这个,但最后我分享了CR的感觉:

这个标题让我想起了学习广义相对论的日子. - CR 13年12月22日7:34

四个理论问题让我很困惑,我找不到好的和简单的解释.在这里他们是,我目前的部分理解(我担心专家将非常有乐趣阅读这个).

欢迎您提供纠正和澄清的帮助(请记住,这适用于初学者,而不是专家).

这种理解有问题吗?

  1. 什么是与编程相关的不变性/协方差/逆变?我最好的猜测是:
    • 这是面向对象编程中遇到的问题.
    • 在查看类和祖先中的方法参数和结果类型时,这必须要做.
    • 这用于方法覆盖重载的上下文中.
    • 这用于在方法参数的类型或方法返回类型与类本身的继承之间建立连接,例如,如果类D是类A的后代,我们可以对参数的类型和方法方法返回类型?
  2. 方差如何与Java方法相关?我最好的猜测是,给定两个A和D类,其中A是D的祖先,以及overhiden/overloaded方法f(arg):
    • 如果两个方法中的参数类型之间的关系与两个类之间的关系相同,则方法中的参数类型称为COVARIANT,具有类型,否则说:A和D中arg类型之间的继承是协变的继承A和D类.
    • 如果参数之间的关系REVERSES类之间的关系,则arg类型表示对类类型的CONTRAVARIANT,否则说:A和D中arg类型之间的继承与A类和D类的继承相反.
  3. 为什么方差理解对Java程序员如此重要?我的猜测是:
    • Java语言创建者已经实现了语言中的差异规则,这对程序员可以做什么有影响.
    • 规则规定覆盖/重载方法的返回类型必须与继承相反.
    • 另一条规则规定,覆盖/重载的参数类型必须与继承协变.
    • Java编译器检查方差规则是否有效,并相应地提供错误或警告.使用差异知识可以更轻松地解密消息.
  4. 过度训练和超负荷有什么区别?最佳的揣测:
    • 当参数和返回类型都是不变的时,方法会覆盖另一个方法.编译器将所有其他情况理解为重载.

java generics inheritance covariance contravariance

6
推荐指数
1
解决办法
2598
查看次数

转换为泛型类型(T)会发出"未经检查的强制转换"警告

关于带有列表的泛型有界类型,我遇到了一个小问题.请帮忙!

Model.java

public class Model {
}
Run Code Online (Sandbox Code Playgroud)

ClassA.java

public class ClassA<T extends Model> {
    private List<T> models;

    public ClassA() {
        models.add((T) new Model());
    }
}
Run Code Online (Sandbox Code Playgroud)

它在这一行给我一个从模型到T警告的未经检查的强制转换:

models.add((T) new Model());
Run Code Online (Sandbox Code Playgroud)

我知道我收到了这个警告,因为我可以安全地从一个子类投射到一个超级类而不是反过来.

有没有办法解决这个问题,还是我可以安全地压制警告?

java generics list bounded-types

5
推荐指数
1
解决办法
3408
查看次数

避免使用`Boolean.box`

我正在调用一个io.netty.bootstrap.BootStrap具有以下签名的java方法:

public <T> B option(ChannelOption<T> option, T value)
Run Code Online (Sandbox Code Playgroud)

我使用以下代码来调用此方法:

b.option(ChannelOption.SO_KEEPALIVE, true);
Run Code Online (Sandbox Code Playgroud)

这无法编译,出现以下错误:

Error:(57, 30) type mismatch;
 found   : io.netty.channel.ChannelOption[Boolean]
 required: io.netty.channel.ChannelOption[Any]
Note: Boolean <: Any, but Java-defined class ChannelOption is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
      b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
                         ^
Run Code Online (Sandbox Code Playgroud)

我不完全理解这说的是什么,但我理解它抱怨得到一个布尔值,因为它是参数化 Any而不是Boolean.所以我尝试了以下代码,它的工作原理:

b.option(ChannelOption.SO_KEEPALIVE, Boolean.box(true));
Run Code Online (Sandbox Code Playgroud)

这编译和工作.有没有办法让这个更漂亮没有box电话?

有人可以翻译那个编译错误吗?

谢谢.

scala scala-java-interop

5
推荐指数
1
解决办法
588
查看次数

Java:使用时,列表的通用类型参数是协变还是协变?

我对协方差和相反性有些困惑。我们是否说过,在Java中,当我们使用时通常是矛盾的? super X

现在阅读我的书,我理解了以下概念:

这是矛盾的:

method(Predicate<? super X> pred)
Run Code Online (Sandbox Code Playgroud)

但这是协变的:

method(List<? super X> list)  //And then we use add for a list of course
Run Code Online (Sandbox Code Playgroud)

这个概念没有明确地写成我要问你的方式,所以我想知道,这个定义正确吗?如果是,为什么第一个是协变的,为什么最后一个是协变的(如果两者都使用super关键字)?

java generics lambda covariance contravariance

5
推荐指数
1
解决办法
112
查看次数

Scala列表中的对象类型

我的印象是,Scala列表中的每个对象必须具有相同的类型,如果我们需要具有不同类型的集合,则应使用元组.

从Scala的文档来看,List

用于表示类型元素的有序集合的不可变链表的类.

scala> val l1 = List(1,2,3)
l1: List[Int] = List(1, 2, 3)

scala> val l1 = List(1,2,3, "oh really?!")
l1: List[Any] = List(1, 2, 3, oh really?!)
Run Code Online (Sandbox Code Playgroud)

似乎并非如此.毕竟Any它本身是一个有效的Scala类型,一切都可以减少到它.

请澄清

types scala list

0
推荐指数
1
解决办法
2562
查看次数