反编译-子类调用父类的泛型方法,为何不用强转就能得到正确的类型,父类编译的时候不是泛型擦出了吗?

问题描述

子类调用父类的泛型方法,为何不用强转就能得到正确的类型,父类编译的时候不是泛型擦出了吗?

以下面这个简单例子演示:
这是父类

 public abstract class GenericFather<T> {

    public T getT(T t){
        return t;
    }
}

通过反编译可以得知编译后泛型擦出,T都用Object代替了
也就是说只要调用父类方法最后肯定返回的是个Object类型

 public abstract class GenericFather
{

    public GenericFather()
    {
    }

    public Object getT(Object t)
    {
        return t;
    }
}

那么问题来了,为何子类调用父类方法时可以不用强转就得到正确的类型?问题到底出在哪里?

解决方案

泛型子类获取父类的模板类型方法

解决方案二:

你可以写个子类继承你的父类,如果你没有指定泛型类型,那么java编译器会默认泛型类型就是Object的,即父类的方法声明默认成了getT(Object)

//编译器给出警告,GenericFather is a raw type. References to generic type GenericFather<T> should be parameterized
 public class Son extends GenericFather{
   //调用getT时必须制定参数类型就是Object
    Son s = new Son();
        s.getT(t)
}

如果你指定了泛型的具体类型,那么你调用getT时就是指定的类型了,所以不会无论如何都能正确获取到类型的。

解决方案三:

泛型主要就是用于编译期间的类型约束的,如果你要继承这个带有泛型的父类,就必须指定泛型代表的具体类型,例如

 class Child extends GenericFather<T>

这里就不能用,得是具体的类型,并且调用父类方法getT()里传的参数也必须是泛型约束的类型,所以返回的肯定是正确的类型。
所以他不是把Object强转成了正确类型,而是你在编译时候就写成正确类型了

解决方案四:

  class Child extends GenericFather<T>
    //不能使用<T>,必须是具体类型,例如<Date>
时间: 2024-09-15 06:50:27

反编译-子类调用父类的泛型方法,为何不用强转就能得到正确的类型,父类编译的时候不是泛型擦出了吗?的相关文章

转型-关于如何通过子类调用父类的父类中的方法

问题描述 关于如何通过子类调用父类的父类中的方法 package access; class A{ public A(){System.out.println("A created!");} public int f(){ System.out.println("call A.f()"); return 1; } } class B extends A{ public int f(){ System.out.println("call B.f()"

Java中子类调用父类构造方法的问题分析_java

在Java中,子类的构造过程中,必须调用其父类的构造函数,是因为有继承关系存在时,子类要把父类的内容继承下来,通过什么手段做到的?    答案如下:     当你new一个子类对象的时候,必须首先要new一个父类的对像出来,这个父类对象位于子类对象的内部,所以说,子类对象比父类对象大,子类对象里面包含了一个父类的对象,这是内存中真实的情况.构造方法是new一个对象的时候,必须要调的方法,这是规定,要new父类对象出来,那么肯定要调用其构造方法,所以:     第一个规则:子类的构造过程中,必须调

Java里子类调用父类构造方法问题

在Java中,子类的构造过程中,必须调用其父类的构造函数,是因为有继承关系存在时,子类要把父类的内容继承下来,通过什么手段做到的?     答案如下:     当你new一个子类对象的时候,必须首先要new一个父类的对像出来,这个父类对象位于子类对象的内部,所以说,子类对象比父类对象大,子类对象里面包含了一个父类的对象,这是内存中真实的情况.构造方法是new一个对象的时候,必须要调的方法,这是规定,要new父类对象出来,那么肯定要调用其构造方法,所以:     第一个规则:子类的构造过程中,必须

子类调用父类方法的问题

问题描述 子类调用父类方法的问题 父类: package com.example.main;public class Parent { public void print(){ System.out.println(this); }} 子类: package com.example.main;public class Childer extends Parent { public static void main(String[] args) { new Childer().print(); }

重写-JAVA中子类覆盖了父类的方法,是否还有办法通过子类调用父类同一方法?

问题描述 JAVA中子类覆盖了父类的方法,是否还有办法通过子类调用父类同一方法? JAVA中子类覆盖了父类的方法,是否还有办法通过子类调用父类同一方法? 解决方案 使用super.methodName();调用. Java中super关键字指代的是父类. this关键字指代的是自身. 解决方案二: 用super.方法名调用 解决方案三: 试试super.xxx 解决方案四: 直接用super.方法名调用对应的方法

Python实现子类调用父类的方法_python

本文实例讲述了Python实现子类调用父类的方法.分享给大家供大家参考.具体实现方法如下: python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找. 继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的. 子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题

Python子类调用父类方法学习笔记

python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找. 继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的. 子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题 如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父

Python子类调用父类方法实例程序

python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找. 继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的. 子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题 如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父

c#-C#子类对象存放在父类数组里面,提出时要不要先转成子类型

问题描述 C#子类对象存放在父类数组里面,提出时要不要先转成子类型 //这是我们要计算价格的方法 public double totalMoney(ProductFather[] pf) { double money = 0; foreach (var item in pf) { money += item.Price; } return money; } ProductFather是父类,有几个商品类继承他,每个商品类里面都有double price价格属性 ,那么如上面,我遍历这个父类数组,