在集合中,泛型可以把它当做参数传进去,当然,也可以不定义类型,此时它的存储默认的就是object类型的,然而在你取出它的时候需要注意:它需要进行一个向下转型操作。
首先,我们提出一个问题:为什么要使用泛型?
早期的object类型可以接收任意的对象类型,但是在实际的使用中,会存在类型转换的问题。也就存在着隐患,所以java语言提供了泛型来解决这个安全问题。
什么是泛型?泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。
参数化类型,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也就定义成参数形式,然后在使用|调用时传入具体的类型。
java泛型,是JDK5中引入的一个新的特性,泛型提供了编译时类型安全检测机制,泛型的好处就是在编译的时候能够检查类型的安全。
泛型类泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。
一个普通的泛型类 :
//T可以为任意标识符,常见的如T、K、E、V等形式的参数常用于表示泛型 public class Demo{ //name这个成员变量的类型为T,T的类型由外部指定 public T name; T age; public Demo() { } //泛型构造方法形参age的类型也为T,T的类型由外部指定 public Demo(T age) { this.age = age; } public T getName() { return name; } public void setName(T name) { this.name = name; } //泛型方法getAge的返回值类型为T,T类型由外部指定 public T getAge() { return age; } public void setAge(T age) { this.age = age; } public static void main(String[] args) throws NoSuchFieldException { Demo demo = new Demo<>(18); Field fname = demo.getClass().getField("name"); System.out.println(demo.name+" type:"+fname.getType()); } }
总结:1、泛型的类型参数只能是类类型 2、泛型的类型参数可以有多个。 3、如果没有定义具体类型,默认为object。
从泛型类派生子类public class Test_Demo extends Demo泛型接口{ }
public class TestDemo1 implements Comparable泛型通配符{ @Override public int compareTo(Integer o) { return 0; } } public class TestDemo implements Comparable { @Override public int compareTo(T o) { return 0; } }
●类型通配符一般是使用“?”代替具体的类型实参。
**?**代表实际传入的参数类型可以是任意的
public class Demo2 {
public void test1(Demo extends Number> d){
}
public void test2(Demo super Integer> d){
}
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
Demo demo4 = new Demo<>();
// demo2.test2(demo4);
//demo2.test1(demo4);
Demo demo1 = new Demo<>();
demo2.test1(demo1);
demo2.test2(demo1);
Demo demo3 = new Demo<>();
demo2.test1(demo3);
demo2.test2(demo3);
Demo
类型擦除
泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是,泛型代码能够很
好地和之前版本的代码兼容。那是因为,泛到信息只存在于代码编译阶段,在进入JVM之
前,与泛型相关的信息会被擦除掉,我们称之为一类型擦除。
泛型类被类型擦除后,相应的类型就被替换成 Object 类型或者上限类型.
示例:
import java.lang.reflect.Field; public class Demo{ public T name; public T age; public Demo() { } public Demo(T age) { this.age = age; } public T getName() { return name; } public void setName(T name) { this.name = name; } public T getAge() { return age; } public void setAge(T age) { this.age = age; } public static void main(String[] args) throws NoSuchFieldException { Demo demo = new Demo<>(); demo.age=78; Field fage = demo.getClass().getField("age"); System.out.println(demo.age+" type:"+fage.getType()); } }
运行结果:78 type:class java.lang.Object
**补充反射的一个异常问题:**在我们通过反射查看它在运行时的状态信息时通常会出现Exception in thread “main” java.lang.NoSuchFieldException这样的异常。
那这种异常在什么情况下会出现呢?当我们要查看的成员变量它是私有的时,当程序运行时会爆出NoSuchFieldException的异常
如下:
import java.lang.reflect.Field; //T可以为任意标识符,常见的如T、K、E、V等形式的参数常用于表示泛型 public class Demo{ //name这个成员变量的类型为T,T的类型由外部指定 public T name; private T age; public Demo() { } //泛型构造方法形参age的类型也为T,T的类型由外部指定 public Demo(T age) { this.age = age; } public T getName() { return name; } public void setName(T name) { this.name = name; } //泛型方法getAge的返回值类型为T,T类型由外部指定 public T getAge() { return age; } public void setAge(T age) { this.age = age; } public static void main(String[] args) throws NoSuchFieldException { Demo demo = new Demo<>(); demo.age=78; Field fage = demo.getClass().getField("age"); System.out.println(demo.age+" type:"+fage.getType()); } }
运行结果:
解决方法就是把它从私有变量改变成公共变量就好啦!



