区别? (通配符)和Java中的类型参数 [英] Difference between ? (wildcard) and Type Parameter in Java

查看:170
本文介绍了区别? (通配符)和Java中的类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能解释一下这两种方法有什么不同吗?他们是一样的吗?就他们解决的问题而言,他们看起来和我一样。如果它们相同,为什么需要



方法1,无界限

  public static void printList(List<?> list){
for(Object elem:list)
System.out.println(elem +);
System.out.println();
}

方法2,无界:

  public static< T> void printList(List< T> list){
for(Object elem:list)
System.out.println(elem +);
System.out.println();
}

方法1,有界

  public static void printList(List< ;? extends Number> list){
for(Object elem:list)
System .out.println(elem +);
System.out.println();
}

方法2,限制:

  public static< T extends Number> void printList(List< T> list){
for(Object elem:list)
System.out.println(elem +);
System.out.println();


解决方案

他们接受相同的参数类型。



然而,用 T (或其他)标识类型可以引用

编辑:例子:

  public static< T> void printList(List< T> list){
for(Object elem:list)
System.out.println(elem +);
System.out.println();
}

这就足够用于打印字符串表示的例子了,但考虑这个没有错误处理):

  public static< T> T getSecondItem(List< T> list){
T item = list.get(1);
退货项目;
}

返回类型是T,它可以让你安全地做这样的事情,使用编译时类型检查:

pre $ class MyClass {
public void myMethod(){}
}

void somewhere(){
List< MyClass> items = ...;
getSecondItem(items).myMethod();
}

命名类型还可以让您在多个位置共享相同的类型约束,例如:

  public< T> int compareLists(List< T> a,List< T> b){
...
}

如果您没有指定类型,则无法指定 a 和 b 是相同的列表类型(您可以使用 List< ;? extends T> 以获得更大的灵活性)。

还问:为什么我需要?。真正的答案是:你没有。我想这主要是为了美学。 Java努力成为一种精确无干扰的语言。有很多情况下,你根本不在乎你指的是什么类型。在这些情况下,您可以使用,而不使用未使用的类型参数声明混淆代码。


Can somebody explain me what the difference is between these two methods? Are they same? They do look same to me in terms of what they solve. If they are same, why need ??

Method #1, Unbounded

public static void printList(List<?> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

Method #2, Unbounded:

public static <T> void printList(List<T> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

Method #1, Bounded

public static void printList(List<? extends Number> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

Method #2, Bounded:

public static <T extends Number> void printList(List<T> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

解决方案

They are the same in that they accept the same parameter types.

However, identifying the type with T (or whatever) lets you refer to the type elsewhere.

Edit: Examples:

Your unbounded examples do not make full use of the capabilities of parameterized types. You have:

public static <T> void printList(List<T> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

And that's sufficient for that example of printing string representations, but consider this (very contrived, and no error handling):

public static <T> T getSecondItem (List<T> list) {
    T item = list.get(1);
    return item;
}

The return type is T, which allows you to safely do things like this, with compile time type-checking:

class MyClass {
    public void myMethod () { }
}

void somewhere () {
    List<MyClass> items = ...;
    getSecondItem(items).myMethod();
}

A named type also lets you share the same type constraint in multiple places, e.g.:

public <T> int compareLists (List<T> a, List<T> b) {
    ...
}

If you did not name the type, you could not specify the constraint that a and b are the same list type (you could use List<? extends T> for more flexibility).

You also asked "Why do I need ??". The real answer is: You don't. It's mostly for aesthetics, I suppose. Java strives to be a precise and clutter-free language. There are many situations where you simply don't care what type you are referring to. In those cases, you may use ? without cluttering code with unused type parameter declarations.

这篇关于区别? (通配符)和Java中的类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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