有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

泛型构造函数在Java中的作用是什么?

众所周知,您可以使用类型参数在Java中创建泛型类:

class Foo<T> {
    T tee;
    Foo(T tee) {
        this.tee = tee;
    }
}

但您也可以使用泛型构造函数,这意味着构造函数显式接收自己的泛型类型参数,例如:

class Bar {
    <U> Bar(U you) {
        // Why!?
    }
}

我正在努力理解这个用例。这个功能让我做什么


共 (5) 个答案

  1. # 1 楼答案

    实际上,这个构造函数

    class Bar {
        <U> Bar(U you) {
            // Why!?
        }
    }
    

    就像generic method一样。如果你有多个构造函数参数,比如:

    class Bar {
        <U> Bar(U you, List<U> me) {
            // Why!?
        }
    } 
    

    然后可以强制执行约束,即它们与编译器具有相同的时间。而不是让你成为全班通用的

  2. # 2 楼答案

    因为未绑定的泛型类型会擦除为Object,所以它与在构造函数中传递Object是一样的:

    public class Foo {
        Object o;
    
        public Foo(Object o) {
            this.o = o;
        }
    }
    

    。。。但就像传递一个空白Object,除非你在做一些聪明的,否则这几乎没有实际价值

    如果你通过绑定泛型,你会看到好处和胜利,这意味着你实际上可以保证你所关心的类型

    public class Foo<T extends Collection<?>> {
        T collection;
        public Foo(T collection) {
            this.collection = collection;
        }
    }
    

    实际上,这更多的是灵活性,而不是革命性的东西。如果您希望灵活地传递特定类别的类型,那么您可以在这里这样做。如果你,那么标准类就没有问题。这里只是为了方便起见,因为类型擦除仍然是一件事,所以未绑定泛型与传递Object相同(并且具有相同的实用程序)

  3. # 3 楼答案

    在您提供的示例中,很明显U在类的构造函数中不起任何作用,因为它在运行时实际上变成了Object

    class Bar {
        <U> Bar(U you) {
            // Why!?
        }
    }
    

    但假设我希望我的构造函数只接受扩展其他类或接口的类型,如下所示:

    class Foo<T extends Baz> {
        <U extends Bar> Foo(U u) {
            // I must be a Bar!
        }
    }
    

    请注意,该类已经使用了不同的泛型类型;这允许您使用与类定义无关的单独泛型类型

    当然,我从来没有用过这样的东西,也从来没有见过它在使用,但这是可能的

  4. # 4 楼答案

    我想到的用例可能是,有些人想要一个从两种类型继承的对象。例如,实现2 interfaces

    public class Foo {
    
        public <T extends Bar & Baz> Foo(T barAndBaz){
            barAndBaz.barMethod();
            barAndBaz.bazMethod();
        }
    }
    

    虽然我从未在生产中使用过

  5. # 5 楼答案

    What does this feature let me do?

    至少有三件事是它能让你做的,这是你无法做的:

    1. 表示参数类型之间的关系,例如:

      class Bar {
          <T> Bar(T object, Class<T> type) {
              // 'type' must represent a class to which 'object' is assignable,
              // albeit not necessarily 'object''s exact class.
              // ...
          }
      }
      
    2. <;撤回>

    3. 正如@Lino首先观察到的,它允许您表示参数必须与两个或多个不相关类型的组合兼容(当所有类型(最多只有一个)都是接口类型时,这是有意义的)。参见Lino的答案以获取示例