02. 编程核心内功心法之泛型
泛型
public static void main(String[] args) {
//List list = new ArrayList();
//指定能够存放的数据类型,统一类型防止出现 类型转换异常
List<String> list = new ArrayList();
list.add(1);
list.add("hello");
list.add(new Object());
for (Object obj:list) {
System.out.println((String)obj); //java.lang.ClassCastException
}
}
本质:参数化类型
泛型的擦除
泛型只在编译阶段有效,编译之后JVM会采取去泛型化的措施.
泛型在运行阶段是没有效果
public static void main(String[] args) throws Exception {
List<String> list = new ArrayList();
list.add("1");
list.add("hello");
list.add("2");
for (Object obj:list) {
System.out.println((String)obj);
}
//反射赋值
Class<? extends List> aClass = list.getClass();
Method method = aClass.getDeclaredMethod("add", Object.class);
method.invoke(list,new Object());
System.out.println(list);//没有任何问题
}
一、泛型通配符介绍
1、无边界通配符
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("gupao");
list1.add("bobo");
list1.add("mic");
loop(list1);
}
/**
* < ? > 通用的类型可以是任意类型
*/
public static void loop(List<?> list){
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
}
2、上边界通配符
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("gupao");
list1.add("bobo");
list1.add("mic");
// loop(list1);
List<Number> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
}
/**
* < ? extends Number >
* 通用的类型必须是Number及其子类
* @param list
*/
public static void loop(List<? extends Number> list){
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
}
3、下边界通配符
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("gupao");
list1.add("bobo");
list1.add("mic");
loop(list1);
List<Number> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
loop(list2);
}
/**
* < ? super Number >
* 通用类型必须是Number 到Object类型的对象
* @param list
*/
public static void loop(List<? super Number> list){
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
}
二、泛型的具体使用
规则: 必须先声明再使用
1、泛型的声明是通过”<>”实现
2、约定泛型可以使用单个大写字母来表示 K E T V 等
/**
* 泛型没有声明就直接使用了
* @param t
* @return
*/
public <T> T func(T t){
return null;
}
1、泛型类
public class Fun <T>{
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public Fun(T t) {
this.t = t;
}
}
//PersonBean
public class PersonBean {
private int id;
private String name;
private String password;
//get/set
}
//测试
public static void main(String[] args) {
PersonBean bean = new PersonBean();
bean.setId(1);
bean.setName("Andy");
bean.setPassword("12345");
Fun<PersonBean> pn = new Fun(bean); //PersonBean
Fun<String> s = new Fun("hello"); //String
}
增加了代码的灵活度
2、泛型方法
public class Fun <K,V>{
//普通方法 可以使用 类中定义的泛型
public K method1(K k,V v){
return (K)null;
}
//普通方法 使用方法中定义的泛型
public <T> T method2(T t,V v){
return (T)null;
}
//在静态方法中我们没法使用 类中定义的泛型,想使用需自己定义<k>
public static <K> K method3(){
return null;
}
}
3、泛型接口
public interface CalGeneric <T> {
T add(T a,T b);
T sub(T a,T b);
T mul(T a,T b);
T div(T a,T b);
}
//实现类 - Integer
public class CalIntegerGeneric implements CalGeneric<Integer> {
@Override
public Integer add(Integer a, Integer b) {
return null;
}
@Override
public Integer sub(Integer a, Integer b) {
return null;
}
@Override
public Integer mul(Integer a, Integer b) {
return null;
}
@Override
public Integer div(Integer a, Integer b) {
return null;
}
}
//实现类 - Double
public class CalDoubleGeneric implements CalGeneric<Double>{
@Override
public Double add(Double a, Double b) {
return null;
}
@Override
public Double sub(Double a, Double b) {
return null;
}
@Override
public Double mul(Double a, Double b) {
return null;
}
@Override
public Double div(Double a, Double b) {
return null;
}
}