当前位置: 首页 > news >正文

百度网站降级的原因计算机一级考试网站怎么做

百度网站降级的原因,计算机一级考试网站怎么做,wordpress 4.5.3 下载,wordpress 删除角色一、泛型是什么?1. 定义: 泛型允许你在定义类、接口或方法时使用类型参数(Type Parameter)。在使用时(如声明变量、创建实例时),再用具体的类型实参(Type Argument) 替换…

一、泛型是什么?

1. 定义:
泛型允许你在定义类、接口或方法时使用类型参数(Type Parameter)。在使用时(如声明变量、创建实例时),再用具体的类型实参(Type Argument) 替换这个参数。它就像是方法的形参和实参,但操作的对象是类型本身。

2. 核心目的:

  • 类型安全(Type Safety):在编译期就能检查类型是否正确,将运行时错误(ClassCastException)转变为编译期错误。

    // 没有泛型:编译通过,运行时报 ClassCastException
    List list = new ArrayList();
    list.add("Hello");
    Integer num = (Integer) list.get(0); // 运行时错误!// 有泛型:编译期直接报错,无法通过编译
    List<String> list = new ArrayList<>();
    list.add("Hello");
    Integer num = list.get(0); // 编译错误:不兼容的类型
  • 消除强制类型转换(Eliminate Casts):代码更简洁、清晰。

    // 没有泛型
    String str = (String) list.get(0);// 有泛型
    String str = list.get(0); // 自动知道是String,无需强转

二、泛型擦除(Type Erasure)—— 泛型的实现原理

这是 Java 泛型的核心机制,也是很多限制的根源。

1. 是什么?
Java 的泛型是在编译器层面实现的,而不是在运行时。在编译后,所有的泛型类型信息都会被移除(擦除)。编译器在生成字节码时:

  • 将泛型类型参数替换为它的边界(Bound)(如 T extends Number 则替换为 Number)。

  • 如果类型参数是无边界的(如 <T>),则替换为 Object

  • 随之插入必要的强制类型转换,以保持类型安全。

2. 例子:

// 源代码(编译前)
public class Box<T> {private T value;public void set(T value) { this.value = value; }public T get() { return value; }
}Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get(); // 无需强转// 编译后(概念上,字节码级别)
public class Box { // T 被擦除private Object value; // T 被替换为 Objectpublic void set(Object value) { this.value = value; }public Object get() { return value; } // 返回Object
}Box stringBox = new Box(); //  raw type
stringBox.set("Hello");
String value = (String) stringBox.get(); // 编译器插入了强转!

3. 带来的影响与限制:

  • 不能使用基本类型:如 List<int> 是错误的,必须用 List<Integer>。因为擦除后是 Object,而 Object 不能持有 int

  • instanceof 和 getClass():运行时无法检测泛型类型。

    List<String> list = new ArrayList<>();
    System.out.println(list instanceof List<String>); // 编译错误
    System.out.println(list instanceof List); // 正确,但只能检查到是List,不是List<String>
  • 不能创建泛型数组new T[] 或 new List<String>[] 都是错误的。因为数组需要在运行时知道其确切的元素类型来保证类型安全,而擦除破坏了这个机制。

  • 不能实例化类型参数new T() 是错误的,因为擦除后是 new Object(),这通常不是你想要的。


三、桥接方法(Bridge Method)—— 保护多态

桥接方法是编译器为了解决类型擦除多态冲突而自动生成的方法。

场景: 当一个类继承或实现了一个泛型类/接口,并重写了其中的泛型方法时。

例子:

// 泛型接口
public interface Comparable<T> {int compareTo(T other);
}// 实现类
public class String implements Comparable<String> {// 我们重写的方法签名:int compareTo(String other)@Overridepublic int compareTo(String other) { ... }
}

由于类型擦除,父接口 Comparable 中的方法在字节码层面变成了 int compareTo(Object other)。这导致子类 String 实际上有两个方法:

  1. int compareTo(String other) (我们自己写的)

  2. int compareTo(Object other) (编译器生成的桥接方法

桥接方法内部做了什么?

// 编译器生成的桥接方法(概念上)
public int compareTo(Object other) {// 在桥接方法中,进行类型检查和安全地向下转型return compareTo((String) other); // 调用我们重写的那个具体类型的方法
}

桥接方法确保了即使在类型擦除后,Java的多态机制(父类引用调用子类方法)也能正常工作,同时保证了类型安全。


四、泛型继承和通配符(Wildcards):extends & super

这是泛型中最难理解但最强大的部分,通常用 PECS(Producer-Extends, Consumer-Super) 原则来概括。

1. 泛型不变性(Invariance)
首先,理解这一点至关重要:Box<String> 和 Box<Object> 没有继承关系,即使 String 是 Object 的子类。

Box<Object> box = new Box<String>(); // 编译错误!不兼容的类型

这种特性称为不变性(Invariance)。它保证了类型安全。如果上面成立,你就可以 box.set(new Integer(100)),从而把一个 Integer 放进一个声明为 String 的盒子里。

2. 通配符 ?
为了解决需要泛型协变的需求,引入了通配符 ?

3. 上界通配符 ? extends T (Producer)

  • 含义:表示“未知的某种类型,但它是 T 或 T 的子类”。

  • 用途:当你主要从泛型结构中读取数据(Producer) 时使用。

  • 规则:你可以安全地从中读取(赋值给 T 或父类引用),但不能向其写入(除了 null)。因为编译器不知道具体是哪种子类,写入可能破坏类型安全。

    List<? extends Number> numbers = new ArrayList<Integer>(); // 协变,允许
    Number num = numbers.get(0); // OK, 可以读取为Number
    numbers.add(new Integer(100)); // 编译错误!不能写入

4. 下界通配符 ? super T (Consumer)

  • 含义:表示“未知的某种类型,但它是 T 或 T 的父类”。

  • 用途:当你主要向泛型结构中写入数据(Consumer) 时使用。

  • 规则:你可以安全地向其写入 T 或 T 的子类对象,但读取出来只能赋值给 Object 引用。因为编译器只知道容器里是 T 的父类,无法确定具体类型。

    List<? super Integer> list = new ArrayList<Number>(); // 逆变,允许
    list.add(new Integer(123)); // OK, 可以写入Integer及其子类
    Integer num = list.get(0); // 编译错误!无法安全读取
    Object obj = list.get(0); // OK, 只能读取为Object

5. PECS 原则总结

  • Producer-Extends (P-E):如果你需要一个提供(生产) T 对象的泛型结构(主要调用 get()),使用 <? extends T>。例如:Collection<? extends T>.get()

  • Consumer-Super (C-S):如果你需要一个接收(消费) T 对象的泛型结构(主要调用 add()),使用 <? super T>。例如:Collection<? super T>.add(T)

  • 既生产又消费:如果你既要读又要写,那就不要用通配符,直接用确切的类型,如 <T>

经典应用:Collections.copy()

public static <T> void copy(List<? super T> dest, List<? extends T> src) {// dest 是消费者 (Consumer),消费T对象,所以用 ? super T// src 是生产者 (Producer),生产T对象,所以用 ? extends Tfor (int i =0; i < src.size(); i++) {dest.set(i, src.get(i));}
}

五、常见问题总结

Q:“详细讲讲Java的泛型。”

A:

“Java泛型的核心目的是提供编译时类型安全消除强制类型转换。它的实现机制是类型擦除,即在编译后泛型信息会被移除,类型参数会被替换为它的边界或Object,并由编译器自动插入强制转换。

类型擦除带来了一些限制,比如不能使用基本类型、不能进行泛型的instanceof检查、不能创建泛型数组等。为了解决擦除与多态的冲突,编译器会生成桥接方法,它在子类重写泛型方法时,负责进行类型检查和安全转型,从而保证多态性。

泛型具有不变性Box<String> 不是 Box<Object> 的子类。为了更灵活的API设计,引入了通配符 ? 和 PECS原则

  • ? extends T 用于生产者,表示可以安全读取,但不能写入。

  • ? super T 用于消费者,表示可以安全写入,但读取受限。

http://www.dtcms.com/a/577632.html

相关文章:

  • 复数的矩阵表示 | 欧拉恒等式的复数矩阵变换
  • Linux 系统调用在 ARM 上的实现与工作机制
  • 红松小课如何成为激活老年人生活的新引擎?从兴趣学习到价值重塑!
  • 怎么才能去定义自己的生活呢?
  • 嘉兴云建站模板重庆网站备案大厅
  • Java并发实战:ConcurrentHashMap原理与常见面试题
  • 前端FAQ: 在React中,如何优化⼤列表的渲染性能?
  • 华硕ROC奥创中心Armoury Crate服务崩溃解决办法
  • 工业软件国产替代:突破“卡脖子”,筑牢制造业升级基石
  • 大专生就业是否存在学历歧视?
  • Java 8 Stream API 进阶实战:从基础到业务落地的全解析​
  • Java117 最长公共前缀
  • 共聚焦显微镜(LSCM)的针孔尺寸标准解析
  • 长春网站优化方式投票链接制作
  • 酷炫的网站欢迎页面wordpress图片分页
  • 深入理解 flex-shrink:CSS 弹性布局中的 “收缩” 智慧
  • React+Tailwind CSS+Shadcn UI
  • 神经网络—— 优化
  • 有名的网站制怎样才能把网站宣传做的更好
  • MIPI DSI和MIPI Tx IP 的建立
  • 基于时间的 SQL 盲注-延时判断和基于布尔的 SQL 盲注
  • 个人微信公众号怎么做微网站seo完整教程视频教程
  • C++_chapter10_C++IO流类库
  • 树莓派5-docker里的ros常用命令
  • 网站地图1 500 怎么做网站推广方案及预算
  • 餐饮网站方案一个完整的网站怎么做
  • 弄一个关于作文的网站怎么做如何建立网站卖东西
  • 在Ubunutu上学习C语言(二):数组和指针
  • 成品网站源码78w78使用方法网站建设服务领域
  • ESP32内存分布全解析