Java泛型使用

Java泛型

本质就是参数化类型

1. 泛型的擦除

泛型只在编译阶段有效,编译之后JVM会采取去泛型化的措施。

泛型在运行时是没有效果的。

public static void main(String[] args) throws Exception {
List<String> list = new ArrayList<>();
list.add("elian");
list.add("gupao");
list.add("hello");
for (Object obj :
list) {
System.out.println((String) obj);
}
// 通过反射的方式添加元素
Class<? extends List> aClass = list.getClass();
Method add = aClass.getDeclaredMethod("add", Object.class);
add.invoke(list, new Object());
System.out.println(list);
}

2. 泛型通配符介绍

2.1 无边界通配符介绍

通用类型
public class FanxDemo02 {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("elian");
list1.add("hello");
loop(list1);
List<Number> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
loop(list2);
}
public static void loop(List<?> list) {
for (Object o : list) {
System.out.println(o);
}
}
}

任何类型都可以作为List的泛型进行传递。

2.2 上边界通配符

image-20220228161357657

代表从Number往下的所有子类都可以使用

image-20220228162237442

上边界指定了通用类型的上限,String这里就不能作为List的泛型进行传递了。

2.3 下边界通配符

表示必须是Integer及其父类直到Object所有对象都可以
public static void loop(List<? super Integer> list) {
for (Object o : list) {
System.out.println(o);
}
}

3. 泛型的具体使用

规则:

  • 必须先声明,再使用
  • 泛型的声明是通过"<>"实现
  • 约定泛型可以使用单个大写字母来表示
public <T>T get(T t) { // 必须先声明<T>才能用T作为返回值类型
return t;
}

4. 泛型类

public class FanxPerson <T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
@Override
public String toString() {
return "FanxPerson{" +
"t=" + t +
'}';
}
public static void main(String[] args) {
FanxPerson<Person> person1 = new FanxPerson<>();
FanxPerson<String> person2 = new FanxPerson<>();
Person person = new Person();
person.setAddr("北京通州");
person.setAge(26);
person.setName("Elian");
person1.setT(person);
person2.setT("Hello");
System.out.println(person1);
System.out.println(person2);
}
}
class Person {
private String name;
private Integer age;
private String addr;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", addr='" + addr + '\'' +
'}';
}
}

可以增加代码灵活度。

5. 泛型方法

public class FanxMethod <K, V> {
// 直接使用方法声明的泛型
public V methode(K k, V v) {
return v;
}
// 因为static静态方法
// 对象中的泛型,只有在创建的之后才能知道类型
// 所以static方法中泛型必须单独声明
public static <K, V>K method( K k, V v ) {
return k;
}
// 在返回值之前声明新的泛型
public <T> T meth1( T t, V v ) {
return t;
}
public <T> void meth2( T t, V v ) {
}
}

6. 泛型接口

public interface CalculateGeneric <T> {
T add( T a, T b );
}
class CalculateIntegerGeneric implements CalculateGeneric<Integer> {
@Override
public Integer add(Integer a, Integer b) {
return a + b;
}
}
class CalculateDoubleGeneric implements CalculateGeneric<Double> {
@Override
public Double add(Double a, Double b) {
return a + b;
}
}
posted @   coderElian  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示