相关疑难解决方法(0)

为什么List <String>不能作为List <Object>?

考虑下面doSomething(List<Object>)接受List<Object>作为参数的方法.

private void doSomething(List<Object> list) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

现在考虑下面的代码片段,它试图调用doSomething()我尝试传递List<String>给的地方doSomething()

List<Object> objectList;
List<String> stringList;

doSomething(stringList); // compilation error incompatible types
doSomething(objectList); // works fine 
Run Code Online (Sandbox Code Playgroud)

即使在代码下面也会引发编译错误

objectList = stringList;  // compilation error incompatible types
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么List<String>不能传递给接受的方法List<Object>

java generics casting

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

如果Generics支持子类型,哪种类型的安全性会丢失?

考虑一下片段:

Number[] numbers = {1, 2.3, 4.5f, 6000000000000000000L};
Run Code Online (Sandbox Code Playgroud)

完成上述操作Number是完全可以的,是一个抽象类.

继续前进

List<Long> listLong = new ArrayList<Long>();
listLong.add(Long.valueOf(10));

List<Number> listNumbers = listLong; // compiler error    - LINE 3

listNumbers.add(Double.valueOf(1.23));
Run Code Online (Sandbox Code Playgroud)

曾3号线被设计成可以编译成功,我们最终会得到一个ListNumberS,即

for(Number num: listNumbers ){
    System.out.println(num);
}

// 10
// 1.23
Run Code Online (Sandbox Code Playgroud)

这些都是数字.

我在一本书中看到了这个,

泛型不支持子类型,因为它会导致实现类型安全性的问题.这就是为什么List<T>不被视为一个亚型List<S>,其中S是超级型T

如上所述,在这种特殊情况下哪种类型的安全性会丢失,第3行是否需要成功编译?

java generics

30
推荐指数
3
解决办法
1140
查看次数

你为什么不能在Java中使用"List <List <String >>"?

在Java中,为什么以下代码行不起作用?

List<List<String>> myList = new ArrayList<ArrayList<String>>();
Run Code Online (Sandbox Code Playgroud)

它可以工作,如果我改为

List<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();
Run Code Online (Sandbox Code Playgroud)

起初,我想也许你不能有一个界面列表,但我可以创建一个List<Runnable>很好的.

想法?

java list arraylist

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

怎么用<?扩展SomeObject>而不是<SomeObject>

所以我查看了一些Java代码并偶然发现:

List<? extends SomeObject> l;
Run Code Online (Sandbox Code Playgroud)

基本上这个列表接受SomeObject的某些对象 - SomeObject本身或其继承者.但是根据多态性,它的继承者也可以像SomeObject一样,所以这也可以:

List<SomeObject> l;
Run Code Online (Sandbox Code Playgroud)

那么,当第二个选项明确定义并且几乎相同时,为什么有人会使用第一个选项?

java generics polymorphism

29
推荐指数
1
解决办法
4026
查看次数

静态通用方法

你能解释为什么以下有效吗?

public class GenericsTest<T> {

    public void doSomething(T v1, T v2) {

    }

    public static <T> void doSomethingStatic(T v1, T v2) {

    }

    public static <T> void doSomethingStaticList(List<T> v1, List<T> v2)
    {

    }

    public static void main(String[] args) {
        GenericsTest<String> gt = new GenericsTest<>();

        // OK
        gt.doSomething("abc", "abc");

        // Not OK
        gt.doSomething(1, "abc");

        // OK
        doSomethingStatic(1, 2);

        // Still OK
        doSomethingStatic(1, "abc");

        // So why is this not OK?
        List<String> list1=new LinkedList<>();
        List<Integer> list2=new LinkedList<>();
        doSomethingStaticList(list1,list2);
    }
}
Run Code Online (Sandbox Code Playgroud)

T v1, …

java generics

29
推荐指数
2
解决办法
1万
查看次数

Java嵌套泛型类型

为什么必须使用泛型类型Map<?, ? extends List<?>>而不是更简单Map<?, List<?>>test()方法?

public static void main(String[] args) {
    Map<Integer, List<String>> mappy =
        new HashMap<Integer, List<String>>();

    test(mappy);
}

public static void test(Map<?, ? extends List<?>> m) {}

// Doesn't compile
// public static void test(Map<?, List<?>> m) {}
Run Code Online (Sandbox Code Playgroud)

注意到以下工作,并且三种方法无论如何都具有相同的擦除类型.

public static <E> void test(Map<?, List<E>> m) {}
Run Code Online (Sandbox Code Playgroud)

java generics bounded-wildcard unbounded-wildcard

25
推荐指数
1
解决办法
1万
查看次数

无法从List <List>转换为List <List <?>>

原始列表转换为List<?>正常.为什么原始列表列表不能转换为列表List<?>

{   // works
    List raw = null;
    List<?> wild = raw;
}
{   // Type mismatch: cannot convert from List<List> to List<List<?>>
    List<List> raw = null;
    List<List<?>> wild = raw;
}
Run Code Online (Sandbox Code Playgroud)

背景故事(缓解xy问题):

我正在使用的API返回List<JAXBElement>.我碰巧知道它总是如此List<JAXBElement<String>>.我计划循环并构建自己的List<String>,但我在写时试图修复(但不是抑制)原始类型编译器警告List<JAXBElement> raw = api();.

我试过了:

List<JAXBElement<?>> raw = api();
List<JAXBElement<?>> raw = (List<JAXBElement<?>>) api();
Run Code Online (Sandbox Code Playgroud)

但这些给出了类型不匹配错误.

有趣的是,这没有任何警告或错误:

for (JAXBElement<?> e : api()) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

java generics casting raw-types unbounded-wildcard

25
推荐指数
1
解决办法
2561
查看次数

任何简单的方法来解释为什么我不能做List <Animal> animals = new ArrayList <Dog>()?

我知道为什么不应该这样做.但有没有办法向外行人解释为什么这是不可能的.你可以轻松地向外行解释:Animal animal = new Dog();.狗是一种动物,但是一系列的狗并不是动物的清单.

java oop generics covariance

22
推荐指数
5
解决办法
5063
查看次数

为什么我不能使用 Stream#toList 在 Java 16 中收集类的接口列表?

我正在流式传输实现接口的类的对象。我想将它们收集为接口的元素列表,而不是实现类。

这对于 Java 16.0.1 的Stream#toList方法似乎是不可能的。例如在下面的代码中,最后一条语句将无法编译。

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class WhyDodo {

    private interface Dodo { }

    private static class FancyDodo implements Dodo { }

    public static void main(String[] args) {
        final List<Dodo> dodos = Stream.of(new FancyDodo()).collect(Collectors.toList());
        final List<FancyDodo> fancyDodos = Stream.of(new FancyDodo()).toList();

        final List<Dodo> noFancyDodos = Stream.of(new FancyDodo()).toList();
    }
}
Run Code Online (Sandbox Code Playgroud)

我们可以显式地将每个元素从 转换FancyDodoDodo。但至少为了简洁起见,我们也可以使用.collect(Collectors.toList()).

为什么我不能使用 Stream#toList 在 Java 16 中收集类的接口列表?

如果有人有比明确投射更好的解决方案,我也很乐意听到:)

java generics type-inference java-stream java-16

21
推荐指数
3
解决办法
1051
查看次数

数组如何在Java中"记住"它们的类型?

请考虑以下代码:

class AA { }

class BB extends AA { }

public class Testing {

    public static void main(String[] args) {
        BB[] arr = new BB[10];
        AA[] arr2 = arr;

        BB b = new BB();
        AA a = new AA();
        arr2[0] = a; // ArrayStoreException at runtime
        arr2[1] = b;

        List<BB> listBB = new ArrayList<>();
        List listAA = listBB;
        listAA.add("hello world.txt");

    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,ArrayStoreException我尝试了arr2[0] = a.这意味着数组会记住它必须接受的类型.但是List不记得他们了.它只是编译并运行良好.在ClassCastException当我检索对象将被抛出BB.

所以问题是:

  1. 数组如何记住它的类型(我知道它被称为"具体化").这究竟是怎么发生的?

  2. 并且为什么只有阵列才能获得这种功率,但是ArrayList …

java arrays generics arraylist

20
推荐指数
2
解决办法
967
查看次数