Java泛型 学习

思维导图

Java泛型 学习_第1张图片

导学

在之前学过的集合框架中,List和Map都使用了泛型技术来确认其内容的数据类型。
如果不使用泛型,在程序运行阶段,会带来数据类型转型的错误风险。

List<String> list = new ArrayList<String>();
list.add("tom");

for (int i = 0; i < list.size(); i++) {
    String obj = list.get(i);
    System.out.println(obj);
}

List list2 = new ArrayList();
list2.add("helen");
list2.add(2); // 自动装箱成Integer
list2.add(true); // 自动装箱成Boolean
for (int i = 0; i < list2.size(); i++) {
    String obj = (String)list2.get(i); // 此处是有风险的
}

在Java中,使用变量之前,必须要先定义变量的数据类型,存在一种特殊的现象,就是多态(数据类型是父类,实现对象是子类),变量赋值不一定要完全和数据类型一致,可以赋予子类对象给它。

public class Client2 {
	public static void main(String[] args) {
		Point point = new Point();
		point.x = "东经102°";
		point.y = "北纬32°";
		
		point.x = 102;
		point.y = 32;
		
		String s = (String) point.x;
		point.print();
		
	}
}

class Point {
	Object x;
	Object y;
	public void print() {
		System.out.println(x + "" +  y);
	}
}

向下转型会带来数据风险的(ClassCastException)
不使用泛型的缺点:需要强制转换;可向集合中添加任意类型的对象,存在风险
泛型的使用:在接口/类名后的尖括号内加上类型,如 List list=new ArrayList();同时,变量声明时的泛型类和其实现类时的泛型类必须相同,即“=”前后的尖括号中的类型需要一致

class Animal{}
class Cat extends Animal {}
List<Animal> list = new ArrayList<Cat>();
这样是不允许的。变量声明的类型必须匹配传递给实际对象的类型

泛型作为方法参数

案例:
定义一个抽象类Goods,包含抽象方法sell();
分别定义各类商品Book,Clothes和Shoes继承Goods,并实现sell()方法,输出一句话,如sell books
定义一个商品销售类GoodsSeller,模拟销售,包括方法:public void sellGoods(List goods),循环调用list对象的sell() 方法

public abstract class Goods {
	public abstract void sells();
}

public class Books extends Goods{

	@Override
	public void sells() {
		System.out.println("sell books");
	}

}
public class Clothes extends Goods {
	
	@Override
	public void sells() {
		System.out.println("sell clothes");
	}
}
public class Shoes extends Goods {

	@Override
	public void sells() {
		System.out.println("sell shoes");
	}

}
public class GoodsSeller {
	//代表只要goods参数保存的元素是Goods或者Goods的子类,都可以
	public void sellGoods(List<? extends Goods> goods) {
		//调用集合中的sell方法
		for(int i = 0; i < goods.size(); i++) {
			Goods g = goods.get(i);
			g.sells();
		}
	}
}
public class Test {
	public static void main(String[] args) {
		//定义books相关的list
		List<Books> bookLst = new ArrayList<Books>();
		bookLst.add(new Books());
		bookLst.add(new Books());
		//定义Shoes相关的list
		List<Shoes> shoesLst = new ArrayList<Shoes>();
		shoesLst.add(new Shoes());
		shoesLst.add(new Shoes());
		//定义Clothes相关的list
		List<Clothes> clothesLst = new ArrayList<Clothes>();
		clothesLst.add(new Clothes());
		clothesLst.add(new Clothes());
		
		GoodsSeller gdSeller = new GoodsSeller();
		gdSeller.sellGoods(bookLst);
			
	}
}

自定义泛型类

public class Demo {
	public static void main(String[] args) {
		Point<Integer, Integer> p = new Point<Integer, Integer>();
		p3.x = 1;
		p3.x = 2;
		
	}
}

public class Point<T1, T2> {
	T1 x;
	T2 y;
}

类的泛型在className之后定义,只有定义的泛型类型才能在类中使用。
即我们定义只有先定义类名后的泛型标志符的时候,才能使该泛型类使用泛型定义方法和成员变量。

自定义泛型方法

泛型方法不一定要写在泛型类中

/**
* 定义泛型方法
**/
public class GenericMethod {
	//定义泛型方法的时候需要将泛型放在访问修饰符和返回值中间
	public <T extends Number> void print(T t) {
		System.out.println(t.toString());
	}
    public static void main(String[] args) {
		GenericMethod gm = new GenericMethod();
		//可以通过泛型方法实现一个方法传递不同的参数
		//gm.print("123");规定泛型的继承限定之后,该行语句就是错误的了
		gm.print(123);
		gm.print(123f);
	}

}

泛型一般使用于框架设计,在实际的应用开发中较少运行

Java泛型中的标记符含义

  • E - Element (在集合中使用,因为集合中存放的是元素)

  • T - Type(Java 类)

  • K - Key(键)

  • V - Value(值)

  • N - Number(数值类型)

  • ? - 表示不确定的java类型

  • 就是代表键值对的泛型

你可能感兴趣的:(Java软件开发工程,java)