我想知道为什么以下代码不能使用编译时通用类型信息来正确查找最特定的方法重载,而是始终使用适用于所有潜在通用参数的方法。有没有办法在编译时打开通用参数类型,以避免在运行时产生讨厌的反射?

import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class Temp {
    class A<T> {
        T x;
        A(T x) {
            this.x = x;
        }
        String bar = foo(x);

        private String foo(Integer i) {
            return "Int";
        }
        private String foo(String i) {
            return "String";
        }
        private <T> String foo(List<T> l) {
            return "List";
        }
        private <T> String foo(T v) {
            return "Value";
        }
    }

    @Test
    public void IntTest() {
        Assert.assertEquals(new A<Integer>(1).bar, "Int");
    }
    @Test
    public void StringTest() {
        Assert.assertEquals(new A<String>("A").bar, "String");
    }
    @Test
    public void ListTest() {
        Assert.assertEquals(new A<List<String>>(new ArrayList<String>()).bar, "List");
    }
    @Test
    public void LongTest() {
        Assert.assertEquals(new A<Long>(1L).bar, "Value");
    }
}

最佳答案

这是因为编译器将不得不为用于A的每种类型生成不同的类T(因为A.bar的初始化程序将需要调用不同的方法)。决定只生成一个类。这与例如在C ++中,编译器会为所有使用的类型参数生成一个新类型。

换句话说,类型为A<String>的已编译代码将不同于类型为A<Integer>的代码,但是在编译之后,只有类型A

07-24 09:48
查看更多