0 0

关于泛型类方法重写的问题10

现在有一个泛型类如下:
public abstract class Parent<T> {

public int toInfo(T t){
return 0;
}
}
有个子类继承该泛型类:
public class Child extends Parent<String> {

@Override
public int toInfo(String t) {
return super.toInfo(t);
}

}
现在我获取该子类的所有方法
public class Test {

public static void main(String[] args) {
Child c = new Child();
Method[] ms = c.getClass().getMethods();
}
}
发现有两个toInfo方法
1. public int Child.toInfo(java.lang.String)
2. public int Child.toInfo(java.lang.Object)

请问我该如何处理只会得到一个方法public int Child.toInfo(java.lang.String)?
2012年10月13日 08:41

2个答案 按时间排序 按投票排序

0 0

采纳的答案

首先,这个问题在《Java语言规范》中已经提到了,请参考 15.12.4.5 Create Frame, Synchronize, Transfer Control :

引用
Discussion
As an example of such a situation, consider the declarations:


    class C<T> { abstract T id(T x); }

    class D extends C<String> { String id(String x) { return x; } }




Now, given an invocation


    C c = new D();

    c.id(new Object()); // fails with a ClassCastException




The erasure of the actual method being invoked, D.id(), differs in its signature from that of the compile-time method declaration, C.id(). The former takes an argument of type String while the latter takes an argument of type Object. The invocation fails with a ClassCastException before the body of the method is executed.

Such situations can only arise if the program gives rise to an unchecked warning (§5.1.9).

Implementations can enforce these semantics by creating bridge methods. In the above example, the following bridge method would be created in class D:


    Object id(Object x) { return id((String) x); }




This is the method that would actually be invoked by the Java virtual machine in response to the call c.id(new Object()) shown above, and it will execute the cast and fail, as required.


1、对于泛型形参 在实际运行时会进行泛型擦去:
如:
class Parent<T> { 
    public T toInfo(T t){ 
        return t; 
    } 
}
class Child extends Parent<String> { 
    @Override 
    public String toInfo(String t) { 
        return t; 
    } 
} 


实际方法的字节码如下:
public java.lang.String toInfo(java.lang.String);
  Code:
   Stack=1, Locals=2, Args_size=2
   0:   aload_1
   1:   areturn
  LineNumberTable:
   line 27: 0


public java.lang.Object toInfo(java.lang.Object);
  Code:
   Stack=2, Locals=2, Args_size=2
   0:   aload_0
   1:   aload_1
   2:   checkcast       #2; //class java/lang/String    //保证类型是String的
   5:   invokevirtual   #3; //Method toInfo:(Ljava/lang/String;)Ljava/lang/Strin
g;
   8:   areturn
  LineNumberTable:
   line 23: 0

此处我们可以看到多了一个 public java.lang.Object toInfo(java.lang.Object);  此方法叫做bridge方法;

Java虚拟机规范: 即bridge方法是由编译器产生的 不再源代码中存在的。
The ACC_BRIDGE flag is used to indicate a bridge method
generated by the compiler.

可以参考
http://stackoverflow.com/questions/289731/what-java-lang-reflect-method-isbridge-used-for

Child实际对应的方法为(大体):
class Child extends Parent<String> {
    @Override
    public String toInfo(String t) {
        return t;
    }
    @Override
    public Object toInfo(Object t) {  //这是一个 bridge方法
        return (String)t;
    }
}

即public int Child.toInfo(java.lang.Object)  因为泛型信息在编译时要进行泛型擦出,因为为了保证那些如(class Child extends Parent<String> )正常工作,由编译器产生的一个bridge方法。

2012年10月13日 16:08
0 0

提示 可以查一下Java的 synthetic 和 bridge 方法

下午解答

2012年10月13日 09:10

相关推荐

    java 继承泛型类示例

    4. **方法覆盖**:如果子类重写了父类的泛型方法,必须保持方法签名的一致性。这意味着子类方法的返回类型和参数类型必须与父类相同,包括泛型。 5. **桥接方法**:由于类型擦除,编译器有时会自动生成桥接方法以...

    泛型,泛型擦除,桥接方法

    泛型可以应用于接口、类和方法中,称之为泛型接口、泛型类和泛型方法。 泛型接口是指在接口中使用类型参数的接口,例如:`public interface GenericInterface, E&gt; { void show(T value); }`。在这里,`T` 和 `E` 是...

    Android Intent传递泛型类

    然而,对于自定义的泛型类,直接使用putExtra()方法是不行的,因为Intent不支持直接传递复杂对象。此时,我们需要采用序列化(Serialization)或者Parcelable接口来实现数据传递。 **序列化(Serializable)** 1. ...

    Java 继承和方法重写

    方法重写则是继承机制中一个关键的特性,允许子类对父类的方法进行定制化,以满足特定需求。 **一、Java 继承** 1. **定义与语法**: Java 中的继承使用 `extends` 关键字实现。例如,如果 `Animal` 是一个类,`...

    3个泛型项目源码.rar

    泛型类定义了一组类型参数,这些参数在实例化类或使用泛型接口、方法时会被具体的类型替换。例如,C#中的`List&lt;T&gt;`就是泛型类,其中`T`就是类型参数,代表一个未知的数据类型。当我们创建`List&lt;int&gt;`时,`T`就被替换...

    java泛型学习全面页面下载资料

    8. **泛型与多态**:解释泛型如何影响类的继承和多态性,以及如何在泛型类的实例间进行方法重写。 9. **集合框架中的泛型**:深入讲解ArrayList、LinkedList、HashSet、HashMap等集合类如何使用泛型,以及泛型在...

    Java泛型类型擦除后的补偿

    这些方法具有原始类型签名,使得子类可以重写父类的泛型方法。 - 桥接方法在运行时扮演了泛型方法的代理角色,确保了多态调用的正确性。 5. **类型参数的边界**: - 虽然类型擦除会移除类型参数的边界,但它们在...

    Eclipse对泛型类的支持.doc

    3. **重构支持**:在泛型类和方法的重构过程中,Eclipse可以智能地处理类型参数,确保重构不会破坏类型安全。 4. **编译器设置**:Eclipse允许开发者在项目属性中设置使用Java 5的编译器,这样可以启用泛型的语法...

    jdk1.5的泛型实现

    - 泛型方法的重写需要保持类型参数的一致性或扩大范围。 9. 泛型的局限性: - 泛型不能用于基本类型,但可以通过Wrapper类进行操作。 - 不能在泛型类的构造函数中使用泛型类型参数。 - 不能创建泛型数组,但...

    Eclipse对泛型类的支持借鉴.pdf

    而“Missing @Override annotation”警告则鼓励开发者使用@Override注解来明确标识重写的方法,以防止无意的覆盖行为。 Eclipse 3.1对泛型的全面支持,使得开发者可以在IDE中无缝地使用这一强大的特性,同时也提高...

    Java5.0泛型编程

    泛型通过允许在类、接口和方法声明中使用类型参数,解决了这些问题。 1. **泛型的基本语法**: - 类声明:`public class Box&lt;T&gt;{ T item; }` - 接口声明:`public interface Container&lt;T&gt;{ void add(T element); ...

    java 多态的泛型实现

    泛型,又称为参数化类型,允许我们在定义类、接口或方法时使用类型参数,而不是具体的类型。这样做的好处在于可以创建通用的容器类,如ArrayList、LinkedList等,它们可以存储任何类型的对象,同时提供了类型安全的...

    C# Equals 和 GetHashCode 方法重写

    这两个方法通常需要在自定义类中进行重写,以满足特定业务逻辑的需求。 #### 1. Equals 方法 `Equals` 方法用于比较两个对象是否相等。默认情况下,所有对象都继承自 `Object` 类,而 `Object` 类中的 `Equals` ...

    C++泛型编程

    ### C++泛型编程:构建灵活的容器与图形类 #### 概述 在现代软件开发中,**泛型编程**是一种重要的编程范式,它允许程序员编写代码时使用未指定的数据类型,从而提高代码的复用性和灵活性。C++通过模板支持泛型...

    JDK1.5新特性泛型_深入研究.doc

    为了避免上述问题,可以采用泛型的方式重写上述代码。使用泛型后,无需进行显式的类型转换,同时也确保了类型的安全性。 ```java public class GenericsFoo&lt;T&gt; { private T x; public GenericsFoo(T x) { this....

    C#中对继承、 类、虚拟、委托、事件、约束泛型等概念的运用

    本篇将详细介绍C#编程语言中几个核心概念的应用,包括继承、类、虚拟方法、委托、事件以及约束泛型等,并通过具体的代码示例来展示这些概念如何被用于实际编程中。 #### 类与继承 在面向对象编程中,类是基本的...

    理学继承接口与泛型PPT课件.pptx

    【理学继承接口与泛型】是编程领域中关于面向对象设计的重要概念,主要涉及到类的继承、接口的使用以及泛型的应用。以下是对这些知识点的详细解释: 1. **类继承**: - 类继承是面向对象编程的一个关键特性,允许...

    java程序设计实验代码

    本实验的主要目的是使用泛型重写`MyArray`类中的数组复制方法,使其能够处理任意类型的数组。 1. **泛型类定义**:定义了一个名为`MyArray`的泛型类,其中包含一个`arraycopy`方法,该方法接受两个同类型的数组,并...

    Ch06 集合、索引器与泛型.ppt

    【第六章 集合、索引器与...难点在于理解和应用索引器的定义,以及泛型的定义和泛型接口、泛型类、泛型属性和泛型方法的实践。通过学习这些内容,开发者可以编写更高效、更安全的代码,更好地管理和操作各种数据结构。

    实验05 集合类与泛型 实验报告.pdf

    6. **Comparable接口**:Product类实现了Comparable接口,重写了compareTo方法,使得Product对象可以进行比较,实现自定义排序。这在Arrays.sort(products)调用中得到了应用,对产品按照价格进行排序。 7. **...

Global site tag (gtag.js) - Google Analytics