前段时间研究spring中的autowireByType实现原理时,看到了一个方法修饰符bridge,由于以前没有见过这个修饰符,不知道它 表示的具体含义,后面的代码也就看不明白了,原理研究也就搁在那里了,没什么进展。恰好这几天在阅读《JAVA泛型与集合》这本书时,看到了书中有对这个 修饰符的讲解,才稍微有点眉目。原来这个修饰符不是给程序员使用的,而是编译器为了实现泛型而自动产生的。书中描述如下:
As we mentioned earlier, generics are implemented by erasure: when you write code
with generics, it compiles in almost exactly the same way as the code you would have
written without generics. In the case of a parameterized interface such as Compara
ble<T>, this may cause additional methods to be inserted by the compiler; these additional
methods are called bridges.
下面举个列子解释一下这段话的意思。
在JDK1.5之前,是不存在泛型的,对象需要比较时需要实现Comparable接口,此时接口如下:
- interface Comparable {
- public int compareTo(Object o);
- }
可以看出接口中定义了一个接受参数类型为Object的比较方法,而JDK中的Integer对象实现了这个接口,简化的代码列出如下:
- class Integer implements Comparable {
- private final int value;
- public Integer(int value) { this.value = value; }
- public int compareTo(Integer i) {
- return (value < i.value) ? -1 : (value == i.value) ? 0 : 1;
- }
- public int compareTo(Object o) {
- return compareTo((Integer)o);
- }
- }
类中的存在两个比较方法,一个参数类型为Object,是Comparable 接口中定义方法的具体实现,此外,还定义了一个接受Integer参数类型的比较方法,是为了方便前者方法实现而添加的。当一个对象需要和另一个对象比较 时,就需要把后者当做Object对象参入前者的compareTo方法中,这样容易发生意外情况,就是不是Integer的实例,转型的就抛异常了,而 这个通常都不在编译期避免。
在JDK1.5之后可以使用泛型了,比较对象的Comparable接口变成下面的样子了:
- interface Comparable<T> {
- public int compareTo(T o);
- }
可以看出接口没有定义接受Object类型的方法了,而是定义一个接受T类型的方法,这个T类型就代表具体的类类型。
此时,实现了比较方法的Integer类如下:
- class Integer implements Comparable<Integer> {
- private final int value;
- public Integer(int value) { this.value = value; }
- public int compareTo(Integer i) {
- return (value < i.value) ? -1 : (value == i.value) ? 0 : 1;
- }
- }
类中不存在接受Object类型的比较方法,只存在一个接受Integer类型的方法,就可以在编译期避免传入不是Integer的实例时而引起的异常。 此时你用反射查看Integer类的方法时,可以看到一个带有Bridge修饰符接受参数为Object的方法,查看代码如下:
- for (Method m : Integer.class.getMethods())
- if (m.getName().equals("compareTo"))
- System.out.println(m.toGenericString());
执行这段代码,打印结果如下:
- public int Integer.compareTo(Integer)
- public bridge int Integer.compareTo(java.lang.Object)
相关推荐
8. 如果想让一个类中的成员变量只能被同一包中的类访问,应使用默认修饰符,也就是不加任何修饰符。因此,正确答案是B。 9. 要使成员变量m能被方法fun直接访问,需要将其声明为静态(static)。因此,正确答案是C。...
在Java中,volatile是一个修饰符,用于告诉JVM这个变量是随时可能被其他线程修改的,因此每次使用变量时都必须去主存中读取,而不是使用工作内存中的数据。这就保证了多线程环境下,对变量的读取总是能看到最新写入...
Java是一种广泛使用的面向对象的编程语言,其基础知识涵盖了类、构造函数、方法重载、循环、数据类型、字符串处理、访问修饰符、静态变量、switch语句、final关键字、设计模式以及MVC架构等多个方面。以下是对这些...
在类方法中(static),不能使用this或super修饰符 " Q0045 Java中是怎样捕获异常的? "try { //statement01 } catch(Exception e) { //statement02 } finally { //statement03 }" Q0046 一个文件中是否可以有多个...
需要注意的是,Singleton 单类模式隐藏有两个问题:(1)构造方式的访问修饰符为 private,即除了自身以外其他任何类都无法调用,但是通过反射机制的 setAccessible(true) 方法可以访问私有方法和属性。(2)对象...
- Java修饰符:包括public, private, protected, default等,用于控制类、方法、变量的访问权限。 - Java类和对象:涉及到内部类(Inner Class)的概念,以及抽象类(abstract)和静态类(static)的使用。 - ...
- **封装**:通过访问修饰符(public, private, protected)实现数据隐藏,提供公共接口进行交互。 - **继承**:子类继承父类的属性和方法,实现代码复用。 - **多态**:同一接口,不同实现,提供不同的行为,如...
类型修饰符 - **无符号 (Unsigned)**:表示变量只能存储非负值。 - **有符号**:表示变量可以存储正数和负数。 - **空类型 (Void)**:表示没有任何类型,通常用于定义函数返回值为空的情况。 #### 21. 类型定义 ...