泛型
- 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
- 在没有泛型的情况下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显示的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的,对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
- 泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动的和隐式的,提高代码的重用率。
比如:
ArrayList al = new ArrayList();
Dog d = new Dog();
al.add(d);
Dog temp = (Dog)a.get(0);//!!!问题就是出现在这句话!隐藏安全隐患!!如果写成下一句,也不报错!!
//Cat temp = (Cat)a.get(0);//但是运行的时候会报错,就是类型转换出错
使用泛型来解决!
ArrayList<Dog> al = new ArrayList<Dog>();
Dog d = new Dog();
al.add(d);
Dog temp = a.get(0);//这里自动转换,也就变的安全了
泛型的优点
- 类型安全
- 向后兼容
- 层次清晰
- 性能较高,用GJ(泛型java)编写的代码可以为java编译器和虚拟机带来更多的类型信息,这些信息对java程序做进一步优化提供条件。
java的反射机制
也就是说,你现在编写一个类,但是不知道这个类函数的参数或者类的成员变量是什么类型,这个时候写多个就是不明智的选择了,为了提高代码的重用率,我们是用泛型。通过反射机制得到传入参数的类型信息,进一步做处理,一个可以做的事情很多啦。
package sort;
import java.lang.reflect.*;
public class Sort {
public static void main(String [] args){
Gen<String> gen1 = new Gen<String>("字符串");
gen1.showTypeName();
//当尖括号里面传值的时候,会检测后面构造函数中的值是否对应,如果不对应就会报错
Gen<Integer> gen2 = new Gen<Integer>(3);
gen2.showTypeName();
Gen<Bird> gen3 = new Gen<Bird>(new Bird());
gen3.showTypeName();
gen3.showMethods();
}
}
class Bird{
public void cry(){
System.out.println("叽叽叽叽");
}
public void count(){
System.out.println("1 2 3 4 ");
}
}
class Gen<T>{
T o;
public Gen(T o){
this.o = o;
}
public void showTypeName(){
System.out.println("type is :" + o.getClass().getName());
}
public void showMethods(){
//通过反射机制,我们可以得到T这个类型的很多信息,比如方法名,返回值,等等
Method []m = o.getClass().getDeclaredMethods();
for(int i = 0;i < m.length;++i){
System.out.println(m[i].getName());
}
}
}
理解ArrayList<**>
这时候我们可以知道,这个ArrayList后面的尖括号的用处了,就是应用了java中的反射机制,然后判断传入类型的某些信息,所以,当你得到某个值的时候,也会根据反射信息得到的东西自动转换,省去了手动转换。而且也变得更加安全了。