简体   繁体   English

寻求有关类型擦除和类型推断的澄清

[英]Seeking clarification regarding type erasure and type inference

class Undoable<T> {
  T value;
  Deque<Object> history;
      
  Undoable(T t, Deque<Object> history) {
    this.value = t;
    this.history = history;
  }
  
  static <T> Undoable<T> of(T t) {
    return new Undoable<T>(t, new LinkedList<Object>());
  }

  public <R> Undoable<R> flatMap(Function<T, Undoable<R>> mapper) {
    Undoable<R> r = mapper.apply(value);
    Deque<Object> newHistory = new LinkedList<>();
    newHistory.addAll(history);
    newHistory.addAll(r.history);
    return new Undoable<R>(r.value, newHistory);
  }

  public <R> Undoable<R> undo() {
    Deque<Object> newHistory = new LinkedList<>(this.history);
    R r;
    try {
      r = (R)newHistory.removeLast(); //line A
    } catch (NoSuchElementException e) {
      throw new CannotUndoException();
    }
    return new Undoable<R>(r, newHistory);
  }
}

Given the code snippet above, let say we leave Line A as it is and ignore the compilation warning.鉴于上面的代码片段,假设我们保持 A 行不变并忽略编译警告。 What would happen if we如果我们会发生什么

Undoable<Integer> i = Undoable.of("hello").flatMap(s -> {
    Deque<Object> history;
    history = new LinkedList<>();
    history.add(s);
    return new Undoable<Integer>(s.length(), history);
});
Undoable<Double> d = i.undo();

I get that Undoable<Integer> and Undoable<Double> erases to Undoable .我得到Undoable<Integer>Undoable<Double>擦除为Undoable But what does R in the undo() method become?但是undo()方法中的R会变成什么? Does it infer to be Double since Double is the target type of that method call?它是否推断为Double因为Double是该方法调用的目标类型?

I've tried running the code on my machine and it runs fine but I have no idea why.我试过在我的机器上运行代码,它运行良好,但我不知道为什么。 Can anyone shed some light?任何人都可以解释一下吗? Thanks a ton!万分感谢!

The R type it will become Object , even when inferred during the method call, this is because of R been of no use, since you never explicit declared it, like this i.<Double>undo() , in most use cases, parametric types are used in methods to infer the types of the method parameters. The R type it will become Object , even when inferred during the method call, this is because of R been of no use, since you never explicit declared it, like this i.<Double>undo() , in most use cases, parametric在方法中使用类型来推断方法参数的类型。 About your code flow, even with a Undone the d.value is a string, it's because d Undone type will be compiled to object, since the R type could be anything, doesn't have how to compare, in compile time, the type inferred result of the method call with your declaration.关于您的代码流,即使使用 Undone d.value也是一个字符串,这是因为d Undone类型将被编译为 object,因为R类型可以是任何东西,没有如何比较,在编译时,类型使用您的声明推断方法调用的结果。 If you put Undone<Double> d = i.<String>undo() it will throw an error, otherwise if you don't explicit declare, never will throw a cast exception.如果你把Undone<Double> d = i.<String>undo()它会抛出一个错误,否则如果你不显式声明,永远不会抛出一个强制转换异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM