泛型
为什么用泛型?
早期的Object类型可以接收任意的对象类型,但是在实际的使用中, 会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这 个安全问题。
什么是泛型
● 泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。
● 参数化类型,就是将类型由原来的具体的类型参数化,类似于方法中的 变量参数,此时类型也定义成参数形式,然后在使用/调用时传入具体的 类型。
● Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编 译时类型安全检测机制,泛型的好处就是在编译的时候能够检查类型安全。
泛型接口
泛型接口与泛型类的定义及使用基本相同。
public interface Demo<T> { //定义一个泛型接口 }
子类也是泛型类,子类和父类的泛型类型要一致
class A<T> implements Demo<T>{ }
子类不是泛型类,父类要明确泛型的数据类型
public class A implements Demo<String> { }
从泛型类派生子类
子类也是泛型类,子类和父类的泛型类型要一致
class A<T> extends Demo<T>
子类不是泛型类,父类要明确泛型的数据类型
class A extends Demo<String
泛型通配符
eg:
package com.ff.javaforword.generic;
public class TestDemo {
public void test(Demo<? extends Number> d){
}
public void test1(Demo<? super Integer> d){
}
public static void main(String[] args) {
/*
(Demo<? extends Number> d)只能传入number及number的子类
*/
TestDemo testDemo = new TestDemo();
Demo<Integer> demo1= new Demo<>();
testDemo.test(demo1);
Demo<Number> demo2= new Demo<>();
testDemo.test(demo2);
Demo<String> demo3= new Demo<>();
// testDemo.test(demo3);
/*
(Demo<? super Integer> d)只能传入Integer及Integer的父类
*/
Demo<Integer> demo4= new Demo<>();
testDemo.test1(demo4);
Demo<Number> demo5= new Demo<>();
testDemo.test1(demo5);
Demo<String> demo6= new Demo<>();
//testDemo.test1(demo6);
}
}
类型擦除
泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是,泛型代码能够很 好地和之前版本的代码兼容。那是因为,泛到信息只存在于代码编译阶段,在进入JVM之 前,与泛型相关的信息会被擦除掉,我们称之为一类型擦除。 泛型类被类型擦除后,相应的类型就被替换成 Object 类型或者上限类型.
package com.ff.javaforword.generic;
import java.lang.reflect.Field;
public class Demo<T> {
public T name;
public static void main(String[] args) throws NoSuchFieldException {
Demo<String> d= new Demo<>();
d.name="aaa";
Field namef=d.getClass().getField("name");
System.out.println(namef.getType());
}
}
运行结果: