问题标签 [erasure]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
464 浏览

java - 两个具有相同擦除的方法不需要重写等效(或者它们的签名不是它们之间的子签名)?

我正在阅读关于 jdk6 的令人难以置信的书“java scjp 认证程序员指南”,其中有一个关于泛型覆盖的部分。上面描述了 subsignature 和 override-equivalent 并描述了一些我引用的 override-equivalent 示例:

给定一个类中的以下三个泛型方法声明:

static <T> void merge (MyStack<T> s1, MyStack<T> s2) { /*...*/ }

static <T> void merge (MyStack<T> s1, MyStack<? extends T> s2) { /*...*/ }

static <T> void merge (MyStack<T> s1, MyStack<? super T> s2) { /*...*/ }

擦除后,所有三个方法的签名都是:merge(MyStack, MyStack) 即,方法的签名是重写等效的,因此这些方法不会被重载。

我不完全同意这些方法是等效的,事实上我认为这些方法有“名称冲突由擦除”但没有一个是另一个的子签名……可能我错了,所以我想对此有所了解。

子签名的定义让我认为它们不是它们之间的子签名。

在 JSL 6 #8.4.2 方法签名中 ( http://docs.oracle.com/javase/specs/jls/se6/html/classes.html#8.4.2 )

如果两个方法具有相同的名称和参数类型,则它们具有相同的签名。如果满足以下所有条件,则两个方法或构造函数声明 M 和 N 具有相同的参数类型:

  • 他们。具有相同数量的形式参数(可能为零)

  • 它们具有相同数量的类型参数(可能为零)

  • <A1,...,An>为 M 的形式类型参数,令<B1,...,Bn>为 N 的形式类型参数。将 N 的类型中出现的 Bi 重命名为 Ai 后,相应类型变量的边界以及 M 和 N 的参数类型相同。

如果 m2 与 m1 具有相同的签名,或者 m1 的签名与擦除 m2 的签名相同,则方法 m1 的签名是方法 m2 的签名的子签名

...

如果 m1 是 m2 的子签名或 m2 是 m1 的子签名,则两个方法签名 m1 和 m2 是覆盖等效的。

在 JSL 8 # 8.4.2 中。方法签名(http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.2

如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为类型参数之后,则它们具有相同的签名的 M,形参类型相同。

方法 m1 的签名是方法 m2 签名的子签名,如果:

  • m2 与 m1 具有相同的签名,或

  • m1 的签名与 m2 的签名擦除相同。

如果 m1 是 m2 的子签名或 m2 是 m1 的子签名,则两个方法签名 m1 和 m2 是覆盖等效的。

编辑 1

简而言之,我的疑问是,从关于擦除的子签名定义中,我理解“一个没有擦除的签名等于从另一个签名中擦除”..而不是“擦除后的两个签名相等”..它微妙但重要(顺便说一下,等效的覆盖定义是基于子签名定义的,这就是为什么我在子签名方面提出问题)

0 投票
3 回答
1298 浏览

java - instanceof List 和 instanceof List 的区别

我知道我们不能调用instanceof List<E>,因为List<E>它不是可具体化的类型。两者兼而有之instanceof Listinstanceof List<?>但是 Eclipse IDE 建议使用instanceof List<?>.

我想知道为什么它建议 unbound wildcardinstanceof List<?>而不是 raw call instanceof List。未绑定的通配符是否instanceof List<?>比原始调用有任何优势instanceof List

预先感谢。

编辑1:实际上,instanceof Listinstanceof List<?>编译器在编译时将擦除类型相同。但是,除了 Mena 指出的美容原因之外,还有其他理由可以使用instanceof List<?>instanceof List

编辑 2:根据Oracle 的这个条目:

  1. instanceof/cast 表达式的类型是 raw

这种情况经常发生,因为 javac 禁止目标类型是泛型类型的 instanceof 表达式;对于强制转换,编译器稍微宽松一些,因为允许强制转换为泛型类型,但会发出警告(见上文)。无论如何,原始类型应该被无界通配符替换,因为它们具有类似的属性 wrt 子类型。

Object o = new ArrayList<String>(); List<?> list_string = (List)o; //same as (List<?>)o boolean b = o instanceof List; //same as o instanceof List<?>

因此,我们可以推断,除了 Mena 所说的美容原因和限制使用基因外,instanceof Listinstanceof List<?>相同的。

0 投票
1 回答
138 浏览

java - Java中数组和泛型的类型规则

在 Effective Java (2nd) 中第 25 条的最后一段中,它说:

数组和泛型有非常不同的类型规则。数组是协变具体化的;泛型是不变的和被擦除的。

有人可以更好地定义与 Java 中的数组和泛型相关的粗体术语吗?我也不介意一些例子。

0 投票
1 回答
534 浏览

json - 模式匹配中的 Scala 擦除

我必须提取 JSON 响应的信息并评估是否存在某些文件。我正在使用以下方法定义:

该方法通过模式匹配检查 JSON 响应,如果存在具有特定名称的字段,则应返回 true。示例 JSON 响应可能如下所示:

这个实现确实有效,但我很确定有一个更直接/不太复杂的实现来实现这一点。我也收到很多警告,如下所示:

SchemaManager.scala:38: 类型模式 Some[Map[String,Any]] 中的非变量类型参数 Map[String,Any] 未选中,因为它已被擦除消除

谁能提供更好的解决方案,和/或解释我收到的警告?

0 投票
3 回答
110 浏览

java - 带擦除的 Java 类型推断

擦除和类型推断有一些问题。我有以下类层次结构,看起来并不复杂:

我想做的是这样的:

当然,这不起作用,因为 Foo 不完全是Foo<?>. 问题是如何构建这样的 Bar?我需要Bar<Foo<?>>,而不是Bar<Foo>,因为有只接受Bar<Foo<?>>作为参数的方法。欣赏想法。

0 投票
2 回答
100 浏览

java - Java 泛型 - 擦除概念

我有一些代码如下:

据我了解,类型擦除后,类T将变为:

并且 m 过载。

拥有m(Object)and m(String),我希望结果是

然而,结果是

我想知道为什么结果会是这样。

0 投票
0 回答
116 浏览

java - 为什么 Java 6 编译这段代码而 Java 7 不编译?两种方法都有相同的擦除

为什么 Java 6 编译这段代码而 Java 7 不编译?Java 7 报告错误“两种方法具有相同的擦除”。是否可以让 java 7 像 java 6 一样编译这段代码?如果我在 java 6 中编译代码并在 java 7 上运行(代码不能用 java 7 javac 编译),我会遇到任何问题吗?

0 投票
2 回答
62 浏览

scala - 在scala中可以无一例外地转换为错误的类型

前几天我写了一个代码来过滤掉列表中的混合行为。

她是一个示例代码,应该描述我遇到的问题。

也许我在做一些完全错误的事情,但它给我带来了很多问题,我现在必须创建很多代码,我希望通过这个函数使它们更具可读性。

0 投票
3 回答
1273 浏览

scala - 在 Scala 中删除“被擦除消除”警告

我有一个简单的 Scala 函数,可以从Map[String, Any].

此代码工作正常,但它会在编译中发出警告消息。

该行case value if (value.isInstanceOf[Seq[Int]])导致警告,我试图case value @unchecked if (value.isInstanceOf[Seq[Int]])删除警告,但它不起作用。

如何删除警告?

0 投票
1 回答
119 浏览

swift - Swift:类型参数的继承

我正在尝试将具有类型参数的类的对象转换为具有更通用类型参数的同一类的对象,如以下 Swift 代码所示:

不幸的是,也许正如预期的那样,这不起作用,因为WorkingClassA<ParameterClassB>不能“沮丧”成WorkingClassA<ParameterClassA>——我知道 Java 不允许这样做,我希望 Swift 能够更好地支持这样的结构。

有没有其他方法可以做到这一点是 Swift,还是根本不可接受?对我来说,“向上转换”类型参数似乎很好,但可能有充分的理由不允许它?

谢谢!