码迷,mamicode.com
首页 > 其他好文 > 详细

基础篇之泛型<>

时间:2017-09-03 01:10:51      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:常用   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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!