JAVA 泛型问题的函数重载

JAVA function overloading with generic type issue

class Test<T> 中的一种方法,其中 returns 一个整数....

public int getIndex(T a) //generic parameter
    {
        return 1; // purposely left simple
    }

以默认大小 5 实例化的数组:boolean[] arr = new boolean[5]; 现在我有几个重载函数,特意简化了....

public void add(T a) // generic parameter
    {
        add(getIndex(a));
    }

public void add(int a)
{
        //boolean array with default size 5
        arr[a] = true;
    }
}

主线:

public static void main(String[] args) {
     Test<Character> test = new Test<Character>();
     test.add('A'); // throws exception
} 

它总是给我 arrayOutOfBoundException: 65

据我了解,编译器仅将字符识别为 ASCII 整数值,而不是调用具有泛型类型参数的方法,为什么会发生这种情况,如何使其工作? 编辑:当我声明 String 类型的测试时,我让它工作,因为不涉及 ASCII 转换。

'A' 的类型为 char。在Java中,char是数值类型,所以可以赋值给int。此外,当有两个重载方法时 - 一个采用 int,另一个采用盒装类型 Character - 你将得到 int 一个:

class Test {
    static void method(int a) {
        System.out.println("int");
    }
    static void method(Character a) {
        System.out.println("Character");
    }
}
> Test.method('A');
int

特别是,'A' 的整数值为 65,因为这是它的 Unicode 值。所以你实际上是在用值 65 调用 add(int) 方法,而不是 add(Character) 方法,因此是 IOOBE.

要修复它,要么在调用方法时显式转换为 Character,要么将名称更改为 addByIndexaddByValue,这样 Java 就不会 select 基于参数类型的错误。


要理解 为什么 Java 选择 add(int) 方法而不是 add(Character),需要阅读 Java 语言规范. §15.12 部分指定如何解析方法调用:

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

所以 add(int) 方法在第一阶段匹配,因为从 char 转换为 int 不是装箱或拆箱转换;并且选择该方法而不进行方法解析的第二阶段,其中允许从 charCharacter 的装箱转换。

当由于重载导致调用哪个方法不明确时,Java明确定义解析顺序:

  • 完全匹配
  • 隐式和向上转换
  • 自动装箱

有关详细信息,请参见示例

这就是为什么在您的情况下,Java 更愿意将您的 char 隐式转换为 int,而不是将 char 装箱为 Character 并调用通用重载。

Listremove 方法存在同样的问题。考虑:

List<Integer> l = new ARrayList<>();
l.add(10);
l.remove(10); // crash because it calls remove(int) rather than remove(E) with E=Integer

解决方案是不要依赖自动装箱。例如上面的列表,你可以这样写:

l.remove(Integer.valueOf(10));

因此,在您的情况下:

test.add(Character.valueOf('a'), Character.valueOf('b'));