Java 泛型:修订间差异
无编辑摘要 |
无编辑摘要 |
||
(未显示同一用户的1个中间版本) | |||
第1行: | 第1行: | ||
Java 泛型 | Java 泛型 | ||
泛型(generics),即“参数化类型”,用于编写更通用、类型安全的代码。定义时由参数代替具体的类型,使用时传入具体的类型(即形参不指定类型,由实参指定)。 | |||
=== 泛型类型 === | === 泛型类型 === | ||
第19行: | 第19行: | ||
... | ... | ||
} | } | ||
==== 泛型接口 ==== | ==== 泛型接口 ==== | ||
interface Generator<T> { | interface Generator<T> { | ||
T generate(); | T generate(); | ||
} | |||
class StringGenerator implements Generator<String> { | class StringGenerator implements Generator<String> { | ||
第39行: | 第37行: | ||
==== <T extends Comparable<? super T>> ==== | ==== <T extends Comparable<? super T>> ==== | ||
实现 Comparable | 实现 Comparable 接口;输入参数可以是 <T> 或其子孙类。 | ||
=== 判断泛型类型 === | |||
public static <T> T t1(Object t1) { | |||
log(type(t1)); | |||
return (T)t1; | |||
} | |||
public static <A> A t2(A t1) { | |||
log(type(t1)); | |||
return t1; | |||
} | |||
List l1 = new ArrayList<>(); | |||
Map<String, String> m1 = new HashMap<>(); | |||
m1.put("a","1"); | |||
log(t1(l1)); | |||
log(t1(m1)); | |||
=== java 伪泛型 === | |||
Java 和 C++ 都提供了泛型功能,但两者在实现和功能上存在一些关键差异。由于 Java 泛型在某些方面存在限制,因此有时被称为“伪泛型”。 | |||
* 擦除类型信息 | |||
Java 和 C++ 的一个主要区别在于泛型类型信息的处理方式。在 Java 中,泛型类型参数会在编译过程中被擦除,即替换为其原始类型。例如,List<Integer> 会被擦除为 List。这意味着 Java 泛型在运行时并不知道实际使用的具体类型是什么,这限制了一些泛型功能的实现,例如泛型方法和泛型继承。 | |||
C++ 则不会擦除泛型类型信息。这意味着 C++ 泛型在运行时仍然知道实际使用的具体类型,这使得 C++ 泛型可以实现 Java 泛型无法实现的功能,例如泛型方法和泛型继承。 | |||
* 泛型实例化 | |||
Java 和 C++ 对泛型实例化的支持也存在差异。Java 泛型只能实例化为引用类型,不能实例化为基本类型。这意味着不能创建像 List<int> 这样的泛型实例。C++ 则支持泛型实例化为引用类型和基本类型。 | |||
* 类型安全 | |||
由于 Java 泛型在运行时并不知道实际使用的具体类型是什么,因此存在潜在的类型安全问题。例如,如果向 List<Integer> 中添加一个 String 对象,则会导致运行时错误。C++ 泛型由于保留了类型信息,因此在类型安全方面具有更好的优势。 | |||
[[分类:Develop]] | [[分类:Develop]] | ||
[[分类:Java]] | [[分类:Java]] |
2024年5月31日 (五) 10:38的最新版本
Java 泛型
泛型(generics),即“参数化类型”,用于编写更通用、类型安全的代码。定义时由参数代替具体的类型,使用时传入具体的类型(即形参不指定类型,由实参指定)。
泛型类型
泛型类
public class Box<T> { private T content; ... } Box<Integer> intBox = new Box<>(123); Box<String> stringBox = new Box<>("Hello, World!");
泛型方法
private Node root; public <K extends Comparable<K>, V> void insert(K key, V value) { root = insert(root, key, value); ... }
泛型接口
interface Generator<T> { T generate(); } class StringGenerator implements Generator<String> { @Override public String generate() { return "Generated String"; } }
泛型参数
<T extends Comparable<T>
Comparable 是指类型 T 必须实现 Comparable 接口,即 T 之间能比较大小(Java 不支持运算符重载,只能通过 Comparable<T> 接口比较两个对象)
<T extends Comparable<? super T>>
实现 Comparable 接口;输入参数可以是 <T> 或其子孙类。
判断泛型类型
public static <T> T t1(Object t1) { log(type(t1)); return (T)t1; } public static <A> A t2(A t1) { log(type(t1)); return t1; } List l1 = new ArrayList<>(); Map<String, String> m1 = new HashMap<>(); m1.put("a","1"); log(t1(l1)); log(t1(m1));
java 伪泛型
Java 和 C++ 都提供了泛型功能,但两者在实现和功能上存在一些关键差异。由于 Java 泛型在某些方面存在限制,因此有时被称为“伪泛型”。
- 擦除类型信息
Java 和 C++ 的一个主要区别在于泛型类型信息的处理方式。在 Java 中,泛型类型参数会在编译过程中被擦除,即替换为其原始类型。例如,List<Integer> 会被擦除为 List。这意味着 Java 泛型在运行时并不知道实际使用的具体类型是什么,这限制了一些泛型功能的实现,例如泛型方法和泛型继承。
C++ 则不会擦除泛型类型信息。这意味着 C++ 泛型在运行时仍然知道实际使用的具体类型,这使得 C++ 泛型可以实现 Java 泛型无法实现的功能,例如泛型方法和泛型继承。
- 泛型实例化
Java 和 C++ 对泛型实例化的支持也存在差异。Java 泛型只能实例化为引用类型,不能实例化为基本类型。这意味着不能创建像 List<int> 这样的泛型实例。C++ 则支持泛型实例化为引用类型和基本类型。
- 类型安全
由于 Java 泛型在运行时并不知道实际使用的具体类型是什么,因此存在潜在的类型安全问题。例如,如果向 List<Integer> 中添加一个 String 对象,则会导致运行时错误。C++ 泛型由于保留了类型信息,因此在类型安全方面具有更好的优势。