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 上边界通配符
代表从Number往下的所有子类都可以使用
上边界指定了通用类型的上限,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; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)