gpt4 book ai didi

java - Java 有没有像 C++ 模板一样的泛型推导?

转载 作者:行者123 更新时间:2023-12-01 15:13:41 25 4
gpt4 key购买 nike

Java 是否有像 C++ 模板一样的泛型推导?例如:

class Foo<T> {}
class Foo<T extends Foo> {}

使用哪个类取决于什么 T实际上是。

如果Java没有这个特性,我该如何处理这个问题(即不同类型的 T可能有不同的行为)?

最佳答案

我发现关于泛型类型的哲学问题如 Foo<T>往往有点模糊;让我们用一些熟悉的东西来重新定义它,一个简化的 List界面:

interface List<T> {
int size();
T get(int i);
boolean add(T element);
}

一个 List<T>是一个包含 T 实例的列表.您是说希望列表在 T 时具有不同的行为。是 Integer .

阅读 List<T> 很诱人作为“ List 中的 T s”;但事实并非如此。这是一个 List ,只是一个普通的旧 List , 包含 Object s。 <T>是对编译器的指令:
  • 每当我add此列表中的某些内容,请确保 Object我尝试添加可以强制转换为 T .
  • 每当我get此列表中的某些内容,将其转换为 T在我对它做任何事情之前。

  • 所以,像这样的代码:
    List<Integer> list = ...
    Integer i = list.get(0);

    被编译器脱糖为:
    List list = ...
    Integer i = (Integer) list.get(0);

    和这样的代码:
    list.add(anInteger);  // Fine.

    Object object = ...
    list.add(object); // Oi!

    由编译器检查,在第一种情况下显示“正常”,并且“oi!您不能将 Object 添加到此列表!”,编译失败。

    这实际上是所有泛型:它是一种省略强制转换的方法,并让编译器对您的代码进行健全性检查。

    这过去是在预泛型代码中手动完成的:您必须跟踪列表中应该包含什么类型的元素,并确保只添加/获取该类型的内容。

    对于简单的程序,这是可行的;但是对于一个人(或者更确切地说,是一群人)来说,它很快就会变得难以控制。如果编译器可以为您进行检查,这实际上是不必要的认知负担。

    所以,你不能专门化泛型,因为它只是删除了一堆强制转换。如果你不能用类型转换来做,你就不能用泛型来做。

    但是你可以用泛型做专门的事情;您只需要以不同的方式考虑它们。

    例如,考虑 Consumer interface :
    interface Consumer<T> {
    void accept(T t);
    }

    这允许您使用特定类型的实例“做”事情。你可以有一个 Consumer对于 Integer s 和 Consumer对于 Object年代:
    AtomicInteger atInt = new AtomicInteger();
    Consumer<Integer> intConsumer = anInt::incrementAndGet;

    Consumer<Object> objConsumer = System.out::println;

    现在,你可以有一个泛型方法,它采用泛型 ListConsumer同类型(*):
    <T> void doSomething(List<T> list, Consumer<T> consumer) {
    for (int i = 0; i < list.size(); ++i) {
    consumer.accept(list.get(i));
    }
    }

    所以:
    List<Integer> listOfInt = ...
    doSomething(listOfInt, intConsumer);

    List<Object> listOfObj = ...
    doSomething(listOfObj, objConsumer);

    这里的重点是,虽然这里的泛型只是删除强制转换,但它也在检查 T list 也一样和 consumer .你不能写
    doSomething(listOfObj, intConsumer);  // Oi!

    因此,特化来自 doSomething 的定义之外。 .

    (*) 实际上,最好将其定义为 Consumer<? super T> ;见 What is PECS解释一下。

    关于java - Java 有没有像 C++ 模板一样的泛型推导?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59608926/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com