Java基础知识之泛型简单介绍
【摘要】 1、什么是java泛型?
java泛型:英文名称是generics,泛型是jdk5引入的一个新特性,java泛型的本质就是参数化类型,就是所有的操作数据类型被指定为一个参数。对参数化类型进行操作的实体(例如类、接口或方法)称为泛型实体。
2、java泛型类
泛型类:必须先声明,再使用;声明是通过<T,E, ...>实现的;约定泛型可以使用单个大写...
1、什么是java泛型?
java泛型:英文名称是generics,泛型是jdk5引入的一个新特性,java泛型的本质就是参数化类型,就是所有的操作数据类型被指定为一个参数。对参数化类型进行操作的实体(例如类、接口或方法)称为泛型实体。
2、java泛型类
泛型类:必须先声明,再使用;声明是通过
<T,E, ...>
实现的;约定泛型可以使用单个大写字母T、E、K、V等表示
import java.lang.reflect.Field;
public class GenericsSimpleExample { public static void main(String[] args) { A<String , Integer> a0 = new A<>(); a0.t= "testStr"; A<Integer , Integer> a1 = new A<>(); a1.t = 100; // 泛型参数在使用时要引用数据类型,不能是基本数据类型,比如int等等 //A<Integer , int> a2 = new A<>(); // 泛型类如果不指定具体的参数类型,默认数据类型是object Class<A> cls = A.class; Field[] fields = cls.getDeclaredFields(); for (Field field : fields) { System.out.println(field.getName() + ":" + field.getType().getSimpleName()); } // 泛型类在具体实现上可以看出不同数据类型,实践上是相同的数据类型,可以通过hashcode进行验证 System.out.println(a0.getClass().hashCode()); System.out.println(a1.getClass().hashCode()); } static class A <T , E> { public T t; public void test0(T t) { } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
注意要点:
- 泛型类的参数类型不能是基本数据类型,要使用引用数据类型
- 泛型类在不指定具体数据类型时候,默认是使用object类型的
- 泛型类具体使用上可以使用不同的数据类型,实践上是相同的数据类型
3、从泛型类派生子类
- 1、子类是泛型的情况,子类要和父类的泛型类型一致
class A<T> extends B<T>{}
- 1
- 2、子类不是泛型的情况,父类要明确泛型的数据类型
class A extends B<String>{}
- 1
4、泛型接口
泛型接口语法:
interface 接口名称 <泛型标识,泛型标识, ...>{
泛型标识 方法名();
...
}
- 1
- 2
- 3
- 4
- 1、实现类也是泛型类,泛型类型要和接口一致
interface B <T,V> {}
class A<T,V> implements B<T,V>{}
- 1
- 2
- 2、实现类不是泛型类,接口要指定具体的类型
class B implements B<String,Integer>{}
- 1
5、泛型方法
泛型方法语法:
修饰符 <T,E,...> 返回值类型 方法名 (形参列表){
方法体;
}
- 1
- 2
- 3
泛型方法特征:
- 只有声明了
<T>
的方法才是泛型方法,仅仅传参使用了泛型的,不是泛型方法 - 和泛型类一样,也可以使用K、V、T、E等等参数表示泛型
public class GenericsMethodExample { public static void main(String[] args) { A0 a0 = new A0(); a0.test0("hello"); A1<Integer> a1 = new A1<>(); a1.test("hi", "hello"); A1.test1("hello world"); } static class A0 { public <T, E> T test0(T t) { System.out.println("t = " + t); return null; } } static class A1<K> { /** * 泛型方法的类型和泛型类一致时,以具体方法的为准 * @param k * @param t */ public <T, K> T test(T t , K k) { System.out.println("t = " + t); System.out.println("k = " + k); return null; } /** * static方法要使用泛型,必须指定为泛型方法加上{@code <K>} * @param k */ public static <K> void test1(K k) { } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
归纳:
- 泛型方法的类型和泛型类一致时,以具体方法的为准
- static方法要使用泛型,必须指定为泛型方法加上
6、泛型通配符
类型通配符一般是使用?
代替具体的类型实参,所以类型通配符是类型实参,而不是类型形参
public class GenericsWildcardExample { public static void main(String[] args) { A<String> a0 = new A<>(); show(a0); A<Integer> a1 = new A<>(); show(a1); } public static void show(A<?> a){ System.out.println(a.getClass()); } static class A<T> { }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
7、类型通配符上限
语法:
类/接口 <? extends 实参类型>
- 1
要求改泛型类型只能是实参类型或者实参的子类类型
public class GenericsWildcardExample { public static void main(String[] args) { A<A1> a11 = new A<>(); A<A2> a12 = new A<>(); A<A3> a13 = new A<>(); // 只能使用A2及其子类 show0(a12); show0(a13); } public static void show0(A<? extends A2> a) {} static class A<T> { } static class A1{} static class A2 extends A1{} static class A3 extends A2{}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
8、类型通配符下限
语法:
类/接口 <? super 实参类型>
- 1
要求改泛型类型只能是实参类型或者实参的父类类型
public class GenericsWildcardExample { public static void main(String[] args) { A<A1> a11 = new A<>(); A<A2> a12 = new A<>(); A<A3> a13 = new A<>(); // 只能使用A2及其父类 show1(a11); show1(a12); } public static void show1(A<? super A2> a){} static class A<T> { } static class A1{} static class A2 extends A1{} static class A3 extends A2{}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
9、什么是泛型擦除?
泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型有关的信息会被擦除
掉,我们称之为 类型擦除
9.1、无限制类型擦除
import java.lang.reflect.Field;
public class GenericsWipeExample { public static void main(String[] args) { Class<?> cls0 = A.class; Field[] fields = cls0.getDeclaredFields(); for (Field field : fields) { System.out.println(field.getName() + ":" + field.getType().getSimpleName()); } } static class A <T>{ T t; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
打印:
t:Object
9.2、有限制类型擦除
import java.lang.reflect.Field;
public class GenericsWipeExample { public static void main(String[] args) { Class<?> cls1 = A1.class; Field[] fields1 = cls1.getDeclaredFields(); for (Field field : fields1) { System.out.println(field.getName() + ":" + field.getType().getSimpleName()); } } static class A1<T extends Number> { T t; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
打印:
t:Number
9.3、方法类型擦除
import java.lang.reflect.Method;
public class GenericsWipeExample { public static void main(String[] args) { Class<?> cls2 = A2.class; Method[] methods = cls2.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName() + ":" + method.getReturnType().getSimpleName()); } } static class A2<T extends Number> { T t; public <K extends Number> K test(K k) { return null; } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
打印
test:Number
9.4、桥接方法
interface MyInter<T>{
T fun1();
}
class DD implements MyInter<String>{
@Override
public String fun1() { return null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
import java.lang.reflect.Method;
public class GenericsWipeExample { public static void main(String[] args) { Class<?> cls3 = A3.class; Method[] methodss = cls3.getDeclaredMethods(); for (Method method : methodss) { System.out.println(method.getName() + ":" + method.getReturnType().getSimpleName()); } } interface MyInter<T>{ T test(); } class A3 implements MyInter<String> { @Override public String test() { return null; } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
打印:
test:String
test:Object
10、泛型和反射
Class<?> cls0 = A.class;
Field[] fields = cls0.getDeclaredFields();
for (Field field : fields) { System.out.println(field.getName() + ":" + field.getType().getSimpleName());
}
- 1
- 2
- 3
- 4
- 5
文章来源: smilenicky.blog.csdn.net,作者:smileNicky,版权归原作者所有,如需转载,请联系作者。
原文链接:smilenicky.blog.csdn.net/article/details/119549581
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)