通用类在Java 6中编译,但不是Java 7 [英] Generic class compiles in Java 6, but not Java 7

查看:267
本文介绍了通用类在Java 6中编译,但不是Java 7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java 6中有一个正确编译的接口:

I have an interface in Java 6 that compiles correctly:

public interface IMultiMap<K, V> extends Map<K, Set<V>> {

    public int valueSize();

    public boolean put(K key, V value);

    public void clear(Object key);

    public boolean isEmpty(Object key);
}

但在Java 7中,此接口不能编译。我在 boolean put(K,V)得到一个编译错误,它具有与 V put(K,V)。编译器的完整错误:

But in Java 7, this interface doesn't compile. I get a compile error on boolean put(K, V) that it has the same erasure as V put(K, V). The full error from the compiler:

error: name clash: put(K#1,V#1) in IMultiMap and put(K#2,V#2) in Map have the same erasure, yet neither overrides the other
    public boolean put(K key, V value);
  where K#1,V#1,K#2,V#2 are type-variables:
    K#1 extends Object declared in interface IMultiMap
    V#1 extends Object declared in interface IMultiMap
    K#2 extends Object declared in interface Map
    V#2 extends Object declared in interface Map

对于记录,添加任何种类的覆盖都不起作用。我试图明确重写 Map.put ,但错误仍然出现。更改我的 put 的返回类型是无效的,因为这个错误阻止了潜在的错误从来没有达到,如果这个错误是固定的,那么这两个方法将不会相同的名称/参数签名。

For the record, adding any kind of overriding doesn't work. I tried explicitly overriding Map.put, but the error still comes up. Changing the return type of my put is moot since this error is blocking that potential error from ever being reached, and if this error were fixed, then the two methods wouldn't have the same name/parameter signature anyway.

我想我可以尝试Java 6的一些反思,看看实际的参数类型最终是在Java 6的编译字节码。很清楚,两个Java 7方法都被擦除到 put(Object,Object)

I think I might try some reflection on Java 6 and see what the actual parameter types end up being in Java 6's compiled bytecode. It's clear that both Java 7 methods are being erased to put(Object, Object). I'll post the reflection results here once I do that.

在此期间,我的临时解决方法将只是重命名 put putSingle ,但这个新行为是正确的吗?对于Java 7,泛型规范的一些部分是否发生了变化,使旧的Java 6行为出错?或者这是Java 7编译器中的错误?

In the meantime, my temporary workaround will be just to rename put to putSingle, but is this new behavior correct? Did some part of the generics specifications change for Java 7 that makes the old Java 6 behavior wrong? Or is this a bug in the Java 7 compiler?

提前感谢。

我运行反射代码。请查看下面的答案。

I ran the reflection code. Check out my answer below.

推荐答案

我认为这是在1.7中修复的一个错误。摘自此页面

I think it's a bug in 1.6 that was fixed in 1.7. Extract from this page:


提要:类无法定义具有相同已删除签名但两种不同返回类型的两种方法

描述:类无法定义具有相同已擦除签名的两个方法,无论返回类型是否相同。这遵循JLS,Java SE 7版,第8.4.8.3节。 JDK 6编译器允许具有相同的已擦除签名但不同返回类型的方法;此行为不正确,已在JDK 7中修复。

示例:

Synopsis: A Class Cannot Define Two Methods with the Same Erased Signature but Two Different Return Types
Description: A class cannot define two methods with the same erased signature, regardless of whether the return types are the same or not. This follows from the JLS, Java SE 7 Edition, section 8.4.8.3. The JDK 6 compiler allows methods with the same erased signature but different return types; this behavior is incorrect and has been fixed in JDK 7.
Example:



class A {
   int m(List<String> ls) { return 0; }
   long m(List<Integer> ls) { return 1; }
}




此代码在JDK 5.0和JDK 6,并在JDK 7下被拒绝。

This code compiles under JDK 5.0 and JDK 6, and is rejected under JDK 7.

这篇关于通用类在Java 6中编译,但不是Java 7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆