【发布时间】:2011-08-29 01:19:06
【问题描述】:
如果您尝试在下面使用重载函数compute1()、compute2() 和compute5(),它们会导致编译错误:
package com.example.test.reflect;
class JLS15Test2
{
int compute1(Object o1, Integer i, Integer j) { return 1; }
int compute1(String s1, Integer i, int j) { return 2; }
int compute2(Object o1, Integer i, int j) { return 3; }
int compute2(String s1, Integer i, Integer j) { return 4; }
int compute3(Object o1, Integer i, int j) { return 5; }
int compute3(String s1, Integer i, int j) { return 6; }
int compute4(Object o1, Integer i, Integer j) { return 7; }
int compute4(String s1, Integer i, Integer j) { return 8; }
int compute5(Object o1, Integer i, Object j) { return 9; }
int compute5(String s1, Integer i, int j) { return 10; }
public static void main(String[] args)
{
JLS15Test2 y = new JLS15Test2();
// won't compile:
// The method compute1(Object, Integer, Integer) is ambiguous
// for the type JLS15Test2
// System.out.println(y.compute1("hi", 1, 1));
// Neither will this (same reason)
// System.out.println(y.compute2("hi", 1, 1));
System.out.println(y.compute3("hi", 1, 1));
System.out.println(y.compute4("hi", 1, 1));
// neither will this (same reason)
// System.out.println(y.compute5("hi", 1, 1));
}
}
在阅读了 JLS 第 15.12 节之后,我想我明白了......在匹配重载方法的第 2 阶段(允许装箱/拆箱,没有可变参数)中,当确定“最具体的方法”时,JLS 说(实际上)最具体的方法是其形式参数是其他适用方法的子类型,并且原语和对象(例如int 和Integer)永远不是彼此的子类型。所以Integer 是Integer 的子类型,int 是int 的子类型,但Integer 和int 与/r/t 子类型比较不兼容,所以compute1()/ compute2() 对有一个最具体的方法。
(而在compute3() 和compute4() 中,带有String 参数的方法比带有Object 参数的方法更具体,因此程序会打印6 和8。)
我的推理正确吗?
【问题讨论】:
标签: java language-lawyer jls subtype