在泛型中键入擦除和代码生成[重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

我有这个示例代码/层次结构来理解编译器在这种特定情况下的行为。

我有以下类/接口;

#1:

abstract class Vehicle<T extends Steering> {

   protected T mSteering;

   public Vehicle(T mSteering) {
       this.mSteering = mSteering;
   }

   void turnLeft() {
       mSteering.toLeft();
   }

   void turnRight(){
      mSteering.toRight();
   }
}

class Car<T extends Steering> extends Vehicle<T> {

    Car(T mSteering) {
        super(mSteering);
    }

    T getSteering(){
        return mSteering;
    }
}

#2:

interface Steering {
    void toRight();
    void toLeft();
}

class XSteering implements Steering {

    @Override
    public void toRight() {

    }

    @Override
    public void toLeft() {
        System.out.println("steering left by XSteering");
    }
}

public class YSteering implements Steering {

    @Override
    public void toRight() {

    }

    @Override
    public void toLeft() {
        System.out.println("steering left by YSteering");
    }
}

#3:

public static void main(String[] args) {

    Car c1 = new Car<>(new XSteering());
    c1.turnLeft();
    // XSteering steering1 = c1.getSteering(); // DOES NOT COMPILE

    Car c2 = new Car<>(new YSteering());
    c2.turnLeft();
}

代码按预期输出;

steering left by XSteering
steering left by YSteering

所以,当我删除以下行中的注释时;

XSteering steering1 = c1.getSteering();

它不编译。

因此,当在编译期间发生类型擦除时,我希望方法的返回类型被Steering getSteering()替换,因为它是最左边的边界。还行吧。我的问题更多的是关于呼叫网站上发生的事情。由于getSteering()具有泛型返回类型,我也期望编译器在您调用函数的地方添加必要的强制转换,因此您不会添加显式强制转换以使其工作(或者换句话说,编译器不会给出复杂性错误)。在这种情况下,我理解失败的人可以吗?

java generics type-erasure
1个回答
2
投票

你在这里使用raw type Car c1 = new Car<>(new XSteering());这就是为什么没有类型检查,编译器不会添加任何强制转换。 T将是Steering,因为它是T的约束。只需使用:

Car<XSteering> c1 = new Car<>(new XSteering());

查看更多What is a raw type and why shouldn't we use it?

© www.soinside.com 2019 - 2024. All rights reserved.