Tag: type erasure

Java名称冲突错误,尽管方法签名不同

为了好玩,我正在尝试实现一个“MultiMap”集合,就像Apache Commons库中已经存在的那样。 我的“删除(K键,V值)”方法出现了一个有趣的错误。 编译器说有一个名称冲突 – 它与“类型Map的删除(对象,对象)”具有相同的擦除。 但是java.util.Map接口中没有定义这样的方法! 只有一个“remove(Object)”方法 – 带有一个参数,而不是我的两个参数版本。 更有趣的是,如果你通过用“删除(对象键,对象值)”替换我的“删除(K键,V值)”手动删除类型信息,它编译得很好。 有谁能解释这种现象? 我正在运行Java 8,以防万一。 import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MultiMap extends AbstractMap<K, Collection> { private Map<K, Collection> map; public MultiMap() { super(); map = new HashMap(); } //Fine public void clear(K key) { get(key).clear(); } //Fine […]

Java Generics Type Erasure字节代码

根据关于Erasure of Generic Types的java文档, 考虑以下表示单链表中节点的generics类: public class Node { private T data; private Node next; public Node(T data, Node next) } this.data = data; this.next = next; } public T getData() { return data; } // … } 因为类型参数T是无界的,所以Java编译器用Object替换它: public class Node { private Object data; private Node next; public Node(Object data, Node next) { […]

是否可以在包含多个侦听器类型的Java中创建自己的事件侦听器列表?

我正在实现一个客户端 – 服务器系统,其中客户端处于连续阻塞读取循环中,侦听来自服务器的消息。 当收到消息时,我想根据消息的类型引发“事件”,其他GUI类可以添加监听器。 我对C#事件更熟悉,所以我仍然习惯于Java的做事方式。 将有许多消息类型,所以我将需要每个接口,称为MessageTypeAListener,MessageTypeBListener等,每个都将包含一个句柄方法,我的GUI类将实现。 但是,将会有许多类型,而不是维护每种类型的侦听器列表,并且有几个“fire”方法,我想要一个大的侦听器列表和一个类型化的fire方法。 然后,fire方法可以说“只有那些类型是我指定的火灾听众”。 所以例如(伪代码): ListenerList.Add(MessageTypeAListener); ListenerList.Add(MessageTypeBListener); fire(message) { ListenerList.Where(type is T).handle(message) } … fire(message); 但是,类型擦除似乎使这很困难。 我可以尝试投射和捕获exception,但这似乎是错误的。 是否有一种干净的方式来实现这一点,或者为每种类型保留一个单独的侦听器列表更为明智,即使有大量的类型?

实现不兼容的接口

我正在尝试构建一个实现Queue和Map 。 两个接口都定义了remove(Object)方法,但具有不同的返回类型: public interface Collection { //Queue extends Collection, which has the problem method public boolean remove(Object e); //… } public interface Map { public V remove(K key); //… } public class QueuedMap extends AbstractMap implements Queue { public V remove(K key) {/* … */} //ERROR: V is not compatible with boolean //… } […]

Javagenerics,对象和通配符的差异和说明

我希望理解这个概念: T对象 – 通用,将被删除为实际类型。 ? 对象 – 会被抹去什么? Object对象; T之间有什么区别? 和Object ? 我很容易理解#1,但是怎么样: Object var; ? var; 两者有什么区别? 我看过我不能用? 明确地,像T或任何其他变量,那? 与对象有关,而与类型无关。 但实际原因是什么? 为什么我不能只编写一个对象List ( List )而不是一个通配符List ( List )? 因为我不知道两种情况下的对象类型。 另外,我想知道什么是擦除? ?

使用Groovy进行Javagenerics和重载

我使用Groovy,JUnit和EasyMock为我的Java应用程序编写unit testing。 在EasyMock中有几个重载方法capture()已被弃用,注意“由于更难的擦除强制执行,不能在Java 7中编译”。 这些方法将Capture类型的对象作为参数。 除其他外,存在以下方法: static boolean capture(Capture captured) static boolean capture(Capture captured) … static T capture(Capture captured) 在Java中不再允许这样做,但是如果直接从Java调用该代码,则会调用正确的方法。 例如,当您执行此代码时 Capture myClassCapture = new Capture(); mockObject.someMethod(capture(myClassCapture)); 调用正确的方法(列表中的最后一个)。 另一方面,如果从Groovy内部调用相同的代码,则会调用列表中的第一个方法,并在测试中出错。 我认为这与Java和Groovy如何解决这些方法有关。 我的假设是Java在编译时绑定方法,而Groovy试图在运行时找到该方法并采用它可以找到的任何方法(可能是第一个)。 任何人都能解释到底发生了什么吗? 这样可以更精确地理解Java和Groovy之间的不同行为。 我通过将Groovy中的调用委托给Java方法来修复它,它将为我完成这项工作: public class EasyMockUtils { public static T captureObject(Capture captureForObject) { return EasyMock.capture(captureForObject); } } 可能有更好的方法吗?

javap和generics的类型擦除

我正在阅读Herbert Schilds关于java中generics的类型擦除。 据说在类上运行javap应该在类型擦除后给我关于public,package protected和protected字段和方法的字节码信息。 但是,我写了以下课程: class Ambiguity{ T ob1; V ob2; void set(T o){ ob1 = o; } void set(V o){ ob2 = o; } } 并在生成的类文件上运行javap并获得以下输出 编译自“Test.java” class Ambiguity { T ob1; V ob2; Ambiguity(); void set(T); void set(V); } 我期待根据我读到的内容看起来像这样的输出。 Compiled from “Test.java” class Ambiguity { java.lang.Object ob1; java.lang.String ob2; Ambiguity(); void set(java.lang.Object); […]

Java:有界类型的getClass()

当我在使用仿制药时,我发现了一些东西。 在下面的示例中, doStuff1编译但doStuff2不编译: public void doStuff1(T value) { Class theClass = value.getClass(); } public void doStuff2(T value) { Class theClass = value.getClass(); } 所以,我查找了Object.getClass()的文档,发现了这个: 实际的结果类型是Class <? extends | X |> where | X | 是擦除调用getClass的表达式的静态类型。 这让我有点好奇。 为什么getClass()这种方式设计? 如果适用的话,我可以理解将类型转换为它们的原始类,但是我没有明显的理由说明为什么它们必须使它同时杀掉T 有没有一个特定的原因,它也可以摆脱它,或者它只是一个普遍的“让我们摆脱一切因为它更容易;谁会永远需要它”的方法?