标签:常用 print 包装类 创建 数组 return ext cas hash
1.泛型的由来:
原因:在泛型出现之前,针对不同的数据类型时可以通过方法的重载和向上转型的方式指定;
1) 方法的重载:
缺点:代码繁杂,复用性差
public class Demo { private int a; private float b; public void set(int a) { this.a = a; } public void set(float b) { this.b = b; } }
2) 自动转型:
缺点:向下转型编译时检验不到错误,需要手动类型检查(instanceof);
public static void main(String[] args) { Object num=1; //int-->Integer-->Object int num1=(int)num; //jdk1.7以前可以从Object类型转为Integer类型,不能直接强制转转为int类型; String str=(String)num;//编译时检验不到错误,需要手动类型检查(instanceof) System.out.println(str);//运行时抛出java.Lang.ClassCastException异常 }
为了解决以上缺点,以C++为模板参照,在jdk1.5中添加了<>泛型的概念。
2.泛型的优点:
1) 安全:编译时检查类型安全
2) 省心:所有的强制转换是隐式的自动的提高了代码的复用率
3.泛型的常用类型:
1)可以在类中使用,例如:
public class ArrayList<E> extends AbstractList<E> public class HashMap<K,V> extends AbstractMap<K,V>
2)在接口中使用,例如:
public interface Collection<E> extends Iterable<E>
3)在方法的返回类型中使用,例如:
class Demo1<T>{ T age; public T getAge() { return age; } }
4)在方法中使用,例如:
Class Demo{ //静态方法中使用,静态方法优先于对象存在,所有需加<T> public static <T> void test(T t){ System.out.println(t); } public static void main(String[] args) { Demo.test(“a”);//输出a } }
4.通配符
通配符的特征:
1)可以用于声明类型和声明方法的参数上,实例化时需指定,不可以用于声明类的参数上;
2)?只能输入和输出,不能修改;
3)? extends 泛型上限 <=的关系;
4)? super 泛型下限 >=的关系;
5.泛型的嵌套:从外到内一层一层拆分
6.泛型注意点
1)泛型的类型只能是引用类型,不能是基本类型,但是引用参数可以是基本类型的参数,因为会自动封装成相应的包装类
2)泛型的指定在使用时需指定泛型类型
3)泛型字母不能使用在静态属性和静态方法以及常量上,例如 static T,,final T age等
4)泛型子类可以继承泛型父类也可以继承非泛型父类,泛型父类中没有指定的泛型,子类需保留,但无需保证顺序,例如(在接口中类似,JDK1.8中, 接口中静态方法或者被default修饰的非静态方法可以定义有方法体,不需要重写,除此之外为被public static final修饰的常量属性和public abstract修饰的抽象方法):
public class Demo1 { public static void main(String[] args) { Integer t=3; Demo3<Integer,Integer, Integer> demo3 = new Demo3<Integer, Integer, Integer>(); demo3.test1(t); } } abstract class Demo2<T1, T2> { T1 age;// 父类的属性随父类而定 void test1(T1 t) { } } // 没有指定的类型,名称可以更改,无需顺序一致, 泛型父类中没有指定的泛型子类需保留 class Demo3<T1, T3, T2> extends Demo2<T3, String> { T1 age; @Override void test1(T3 t) {// 重写的类型随父类而定,不能写为void test1(T1 t) System.out.println(1); } // 当类型参数为基本类型时,可以对父类方法进行重载 void test1(int t) { System.out.println(2); } }
5)泛型的拭除,父类拭除子类可以拭除,或者子类和父类同时拭除,不能父类拭除而子类不拭除,拭除的泛型类型默认为Object类型,例如(在接口中类似):
public class Demo { class Demo1<T1,T2>{ T2 age; } public static void main(String[] args) { //泛型的拭除,消除警告可以用Object,泛型的拭除相当于Object,但是不完全等同于Object,因为不会进行编译检查 Demo1 demo = new Demo().new Demo1(); System.out.println(demo.age);//输出null } }
public class Demo { static class Demo1<T1, T2> { T1 age = (T1) "1";//T1 没有指定泛型类型,传入String类型参数编译错误; } public static void main(String[] args) { //不会对T1进行类型检查 Demo1<Integer, Integer> demo = new Demo.Demo1<Integer,Integer>(); // demo.age 属于String类不属于Integer if (demo.age instanceof Integer) { System.out.println(1); } if (demo.age instanceof Object) { System.out.println(2); } // if (demo.age instanceof String) { // System.out.println(3); // }//编译错误 因为demo.age类型是String类型的,指定的是Integer类型 } }// 输出结果为2;
6)泛型没有多态,例如 :
public static Demo<Father> test(){ // return new Demo<Son>();//编译错误,Son和Father的类型不一致; // return (Demo<Father>)(new Demo<Son>());//编译错误,Son和Father的类型不一致; return new Demo<Father>(); } public static void test(Demo<Father> d){ } public static void main(String[] args) { // test(new Demo<Son>());// 编译错误 } } class Demo<T>{ } class Father{ } class Son extends Father{ }
7)? extends 泛型上限注意是否是同一个类型 例如:
//public static void test(Demo<?> d){ //} //public static void test(Demo<? extends Father> d){ //}//编译错误
8)没有泛型数组,不能创建泛型数组
---恢复内容结束---
标签:常用 print 包装类 创建 数组 return ext cas hash
原文地址:http://www.cnblogs.com/gg128/p/7468451.html