范型是Java1.5引入的语言特性,它是编译时的一个语法现象,也就是说,对于一个类,不管是范型类还是非范型类,编译得到的字节码是一样的,差别仅在于通过范型这种语法来进行编译时的类型检查,在运行时是没有范型或者类型参数这个说法的。
范型跟反射刚好相反,反射是一种运行时行为,所以编译时不能访问的变量或者方法(比如private),在运行时通过反射是可以访问的,也就是说,可见性也是一种编译时的行为,在运行时,JVM中的字节码对彼此都是可见的。
Java在将源代码编译后,自动去除了关于范型的信息,范型是编译时的语法现象,这给范型的处理带来一些很不直观的结果。
范型类不能用于instanceof判断
package com.tom.lang.generics; public class Generics<T> { public static void main(String[] args) { Generics<String> stringGenerics =new Generics<String>(); if (stringGenerics instanceof Generics<String>) {//编译错, 范型类不能用于instanceof运算符 } } }
范型参数不能作为方法签名的一部分信息
package com.tom.lang.generics; public class Generics<T> { public void method(Generics<String> obj) { //编译错,两个method冲突 } public void method(Generics<Integer> obj) { } }
范型类不能获得Class对象
Data<Integer>.class //范型类加.class来获得它的class对象
范型处理困难
Gson这个GSON算是比较优雅的解决了范型的问题,但是范型的运行时消除这个特性还是给使用Gson带来一些额外的代码,比如如下的代码不用任何额外处理时
package com.tom.lang.generics; import com.google.gson.Gson; class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } class Data<T> { private T data; public Data(T data) { this.data = data; } public T getData() { return data; } } public class DataTest { public static void main(String[] args) { Data<Point> d = new Data<Point>(new Point(100,200)); String str = new Gson().toJson(d); System.out.println(str); Data<Point> dd = new Gson().fromJson(str, Data.class); //虽然dd看上去像是一个带有参数类型为Point的Data范型类变量,实际上运行时得到的结果是,Data含有一个data字段,但是这个字段 //是TreeMap类型的,由于运行的范型消除,所以,即使返回的dd中的data字段是Map类型,仍然不会报错! //Point p = dd.getData(); //运行时,类型转换失败 Map map = dd.getData(); //成功 } }
上面的正确做法
package com.tom.lang.generics; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } class Data<T> { private T data; public Data(T data) { this.data = data; } public T getData() { return data; } } public class DataTest { public static void main(String[] args) { Data<Point> d = new Data<Point>(new Point(100,200)); String str = new Gson().toJson(d); System.out.println(str); Type type = new TypeToken<Data<Point>>(){}.getType();//将范型类型包装到TypeToken中保存 Data<Point> dd = new Gson().fromJson(str, type); //转型正确 Point p = dd.getData();//可以正确取值 } }
相关推荐
- **避免强制类型转换**:使用泛型可以消除不必要的类型转换,提高代码的稳定性。 - **容器类的使用**:Java集合框架中的类如`ArrayList`、`LinkedList`等都支持泛型,确保元素的类型安全。 总之,Java泛型通过...
此外,Java泛型还有擦除的概念,即在编译后,泛型信息会被消除,转而使用原始类型。这是因为Java的泛型是类型安全的,但不是运行时类型检查的。尽管如此,泛型仍然在编译时提供了类型检查,使得我们能够在开发阶段就...
2. **消除类型转换**:泛型对象可以直接使用指定的类型,无需手动转换。 3. **代码重用**:泛型可以应用于不同的数据类型,提高了代码的可复用性。 4. **强类型提示**:使得代码更易读,因为类型信息在编译时已经...
泛型的主要目标是消除强制类型转换,防止在运行时出现类型错误,并提高代码的可读性和复用性。 1. **泛型的基本概念** - **类型参数(Type Parameter)**:泛型中的`T`、`E`等字母被称为类型参数,它们代表了待...
2. **消除类型转换**:泛型集合可以直接存储和检索指定类型的对象,无需手动转换。 3. **代码重用**:泛型允许编写通用的代码,适应多种数据类型。 掌握Java泛型对于高效、安全地使用Java集合框架至关重要,它也...
其次,范型(Generics)是Java 5引入的新特性,它的目的是为了增强类型安全性,并消除运行时的类型检查。范型允许我们在创建集合时指定其元素类型,从而避免了类型转换错误和潜在的ClassCastException。 1. 泛型类...
使用泛型后,编译器会在编译时检查类型一致性,从而消除运行时类型转换错误的风险。 ### 总结 Java泛型是一项强大的特性,它提供了类型安全的集合操作,增强了代码的重用性和可维护性。通过使用泛型,你可以编写...
在分布式存储系统中,不同类型的存储系统范型具有其特定的架构和实现。分布式文件系统如Google文件系统、TaobaoFileSystem和FacebookHaystack等,它们有着各自的系统架构和设计。内容分发网络如CDN,是用来高效分发...
泛型在Java中引入于JDK 5.0,它的主要作用是消除类型转换异常,并提供编译时的类型检查。通过使用尖括号`<T>`来定义泛型,其中`T`代表一个类型参数,可以是任何引用类型,例如String、Integer等,或者自定义的类如...