泛型1
泛型的概念
泛型类的声明与使用
泛型接口的声明与使用
泛型的好处
泛型的概念
如果没有泛型的话,只能用object来接收所有的参数,这样太混乱,也可能出现类型转换错误。
package java20180201_1; class Wrapper { private Object data; int i; public Wrapper(Object data) { this.data = data; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } } public class NoGenericsDemo { public static void main(String[] args) { Wrapper w1=new Wrapper("stt"); Wrapper w2=new Wrapper(new Integer(100)); Wrapper w3=new Wrapper(100); /** * java.lang.String cannot be cast to java.lang.Integer * java.lang.Integer cannot be cast to java.lang.String * compile-time and run-time * 放进去可以,取出来有时也可以,虽然语法上不会有问题,但运行时就会有问题。 */ // Object d1=w1.getData();//Object范围太大了,希望再具体一点,那么这个时候这种写法就太麻烦,也会有问题。所以才用泛型。 String d1=(String) w1.getData(); Integer d2=(Integer) w1.getData(); // String d3=(String) w3.getData(); } }
泛型类的声明与使用
package java20180201_1; class WrapperDemo<T> { private T data; int i; public WrapperDemo(T data) { this.data = data; } public T getData() { return data; } public void setData(T data) { this.data = data; } } public class Generics { /** * T是形式类型类型参数,下面的String或Integer是实际类型参数,T不可以是基本类型,可以有多个形参 * @param args */ public static void main(String[] args) { WrapperDemo<String> w1=new WrapperDemo<String>("dfs"); String d1=w1.getData(); //写法有好几种 WrapperDemo<String> w2=new WrapperDemo<String>((new Integer(300)).toString()); WrapperDemo<Integer> w3=new WrapperDemo<Integer>(new Integer(300)); WrapperDemo<Integer> w4=new WrapperDemo<>(new Integer(300)); WrapperDemo<Integer> w5=new WrapperDemo<>(100); /* * 普通类继承泛型接口 */ MyImpl w6=new MyImpl(); String s=w6.test("df"); /* * 泛型类继承泛型接口 */ MyImpl2<String> w7=new MyImpl2<>(); String s1=w7.test("String"); } }
这个类同时也是下面泛型接口的调用类
泛型接口的声明与使用
package java20180201_1; public interface GenericInterface <T>{ T test(T t); } ============================== 普通类的泛型接口 package java20180201_1; /* * 实现时要传递一个具体的类型,也就是下面的String样例。 */ public class MyImpl implements GenericInterface<String> { @Override public String test(String t) { return null; } } ================================= 泛型类的泛型接口 package java20180201_1; public class MyImpl2<T> implements GenericInterface<T> { @Override public T test(T t) { return null; } }
泛型的好处
类型安全
消除强制类型转换(放进去是object,取出来还是object,还得强制转换)
===============================================
泛型2
有继承关系的类型参数
泛型与原生类型的关系
类型擦除
堆污染
package java20180202_1; class Wrapper2<T> { private T data; public Wrapper2(T data){ this.data=data; } public T get(){ return data; } } public class GenericDemo2 { //堆污染,可变长参数 public void test(Wrapper2<String>...ws){ } public static void main(String[] args) { Wrapper2<String> w1=new Wrapper2<>("abc"); Wrapper2<Object> w2=new Wrapper2<>(new Integer(100)); /* * 运行时是没有区别的,都是java20180202_1.Wrapper2。T只在编译时有用,在运行时会擦除掉,全部是Object类型的, */ System.out.println(w1.getClass().getName()); System.out.println(w2.getClass().getName()); Wrapper2<Integer> w4=new Wrapper2<>(200); w1=w4; Wrapper2 temp=w4; w1=temp; /* * 非泛型类是就可以将子类赋值给父类的,这叫做向上转型。下面这个是不兼容的 */ // w2=w1; /* * 原生类型与泛型类型,下面是一种典型的向后兼容的做法,将原生类型与泛型类型相互赋值是可以的,但不推荐。 */ Wrapper2 w3=new Wrapper2("cde");//这是raw type,没有泛型的功能 w2=w3; w3=w1; } }
泛型3
泛型方法的声明与调用
泛型构造方法的声明与调用
方法重写与泛型
泛型4
无边界通配符
上边界通配符
下边界通配符