标签: unbounded-wildcard

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
查看次数

Collection <?>和Collection <T>之间有什么区别?

我主要是一名C#开发人员,我正在向我的朋友教授Data Structures,他们在他们的大学里使用Java,我在Java中看到了这样一个表达式:

void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

我还没有在C#中看到这样的东西,所以我想知道Java Collection<T>Collection<?>Java 之间的区别是什么?

void printCollection(Collection<T> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为它也可以用上面的方式编写.在文档中的家伙比较Collection<Object>Collection<T>虽然.

示例来自http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

java generics collections types unbounded-wildcard

23
推荐指数
4
解决办法
1063
查看次数

未绑定通配符与原始类型之间的差异

我正在阅读关于泛型的内容,我不明白是否需要未绑定的通配符以及它与原始类型的区别.我读了这个问题,但仍然没有弄清楚.在未绑定的通配符Java教程页面中,我得到了以下两点,我没有理解第一点:

  • 如果您正在编写可以使用Object类中提供的功能实现的方法.
  • 当代码使用泛型类中不依赖于类型参数的方法时.例如,List.size()List.clear().事实上,Class<?>经常使用,因为大多数方法Class<T>都不依赖T.

有人可以用外行语言解释未绑定的通配符和原始类型之间的区别.

List<?>什么不同List<Object>

java generics unbounded-wildcard

23
推荐指数
4
解决办法
5820
查看次数

在Java中,常规泛型不能做外卡吗?

我是Java新手.在 文档中,他们将此作为使用通配符的用例:

static void printCollection(Collection c) {
    Iterator i = c.iterator();
    for (int k = 0; k < c.size(); k++) {
        System.out.println(i.next());
    }
}
Run Code Online (Sandbox Code Playgroud)

这是他们的解决方案:

static void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我可以在没有外卡的情况下做同样的事情:

static <T> void printCollection(Collection<T> c) {
    Iterator i = c.iterator();
    for (int k = 0; k < c.size(); k++) {
        System.out.println(i.next());
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我一个简单的用例,常规的泛型不起作用,但外卡会吗?

更新:此处的答案何时在Java Generics中使用通配符?不要告诉我们需要通配符.事实上,它是另一种方式.

java generics bounded-wildcard unbounded-wildcard

19
推荐指数
1
解决办法
347
查看次数

(?)通配符泛型类型的不规则

我相信?泛型中的类型是一种特定的未知类型.这意味着,声明让我们说这种类型的列表会阻止我们在其中添加任何类型的对象.

List<?> unknownList;
unknownList.add(new Object()); // This is an error.
Run Code Online (Sandbox Code Playgroud)

编译器按预期给出错误.

但是当未知类型是二级泛型时,编译器似乎并不关心.

class First<T> {}

List<First<?>> firstUnknownList;

// All these three work fine for some reason.
firstUnknownList.add(new First<>());
firstUnknownList.add(new First<Integer>());
firstUnknownList.add(new First<String>());
Run Code Online (Sandbox Code Playgroud)

我想可能编译器根本不关心二级中的泛型参数,但事实并非如此,

List<First<Integer>> firstIntegerList;
firstIntegerList.add(new First<String>()); // This gives a compiler error as expected.
Run Code Online (Sandbox Code Playgroud)

那么,为什么编译器允许我们在第二个例子中只接受一个未知元素(因而没有任何东西)时添加任何类型的元素?

注意:编译器Java 1.8

java generics unbounded-wildcard

17
推荐指数
1
解决办法
633
查看次数

为什么我不能使用通配符(?)作为参数,字段,局部变量的类型,或作为方法的返回类型?

关于泛型中的通配符的Oracle 文档说,

通配符可用于各种情况:作为参数,字段局部变量的类型 ; 有时作为返回类型 (虽然更好的编程实践更具体).

我在下面的类中尝试了所有四个,并且在每个类中都有编译器错误.为什么?我究竟做错了什么?

public class MainClass {
    private ? instanceFieldWithWildCardType;//ERROR
    private static ? staticFieldWithWildCardType;//ERROR

    private void methodWithWildCardParam(? param) {}//ERROR

    private void methodWithWildCardLocalVariable() {
        ? localVariableWithWildCardType;//ERROR
    }

    private ? methodWithWildCardReturnType() {//ERROR
        return null;
    }

    private void methodWithWildCardParam(? param) {}//ERROR

}
Run Code Online (Sandbox Code Playgroud)

java generics wildcard bounded-wildcard unbounded-wildcard

14
推荐指数
2
解决办法
3665
查看次数

List <List <?>>和List <List>是java中不兼容的类型

我没有得到这个代码编译的方式:

List<List> a = new ArrayList();
List<List<?>> b = new ArrayList();

a = b; // incompatible types
b = a; // incompatible types
Run Code Online (Sandbox Code Playgroud)

似乎java 在泛型方面不考虑List并且List<?>是相同的类型.

这是为什么?还有一些不错的出路吗?

上下文

有一个带有以下签名的库函数:public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type).这适用于作为参数传递的简单类型,但在泛型的情况下,结果不会使用通配符进行参数化,从而导致javac抱怨原始类型.我想将结果传播到我的应用程序的其余部分,Set<Class<? extends GenericTypeHere<?>>>但是简单的转换不能像我期望的那样工作.

编辑:解决方案

感谢您的回答,以下是我最终的工作方式:

@SuppressWarnings({"rawtypes", "unchecked"})
private static Set<Class<? extends GenericTypeHere<?>>> factoryTypes() {
    return (Set) new Reflections("...").getSubTypesOf(GenericTypeHere.class);
}
Run Code Online (Sandbox Code Playgroud)

java generics casting raw-types unbounded-wildcard

9
推荐指数
1
解决办法
1030
查看次数

Java Method Unbounded Type or Class Return

I was reading this article, , about subclassing a builder class. I understood the article but there was one small bit that bothered me. There was this method,

public static Builder<?> builder() {
        return new Builder2();
}
Run Code Online (Sandbox Code Playgroud)

When I changed Builder<?> to Builder, a raw type, the compiler would not compile the code. The error was,

Rectangle.java:33: error: cannot find symbol
System.out.println(Rectangle.builder().opacity(0.5).height(250);
Run Code Online (Sandbox Code Playgroud)

What was the additional information passed to the compiler using the additional <?>? I suspected it …

java generics design-patterns unbounded-wildcard

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

过滤流会更改其通配符范围吗?

下面的方法编译没有问题:

static Stream<Optional<? extends Number>> getNumbers(Stream<Number> numbers) {
    return numbers.map(Optional::of);
}
Run Code Online (Sandbox Code Playgroud)

但如果我像这样添加一个简单的过滤:

static Stream<Optional<? extends Number>> getNumbers2(Stream<Number> numbers) {
    return numbers.map(Optional::of).filter(number -> true);
}
Run Code Online (Sandbox Code Playgroud)

它会生成以下错误:

不兼容的类型:
java.util.stream.Stream<java.util.Optional<java.lang.Number>> 无法转换为
java.util.stream.Stream<java.util.Optional<? 扩展 java.lang.Number>>

在 openJdk-11 和 openJdk-17 上进行了测试。

我希望它们都做同样的事情(要么都编译正常,要么都生成相同的编译错误),所以我真的对此感到困惑:这里的一般规则是什么解释了为什么第一种方法编译正常而第二种方法编译正常才不是?谢谢!

java generics unbounded-wildcard java-stream

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