java - Java 中的反射转换和重载方法调度

标签 java reflection overloading

请注意,所有代码都是一个简化示例,以便仅传达我问题的核心思想。经过轻微编辑后,它应该全部编译并运行。

我有几个类都实现了一个公共(public)接口(interface)。

public interface Inter{}
public class Inter1 implements Inter{}
public class Inter2 implements Inter{}

在一个单独的类中,我有一个 Inter 类型的列表,我用它来根据用户输入存储和删除 Inter1 和 Inter2 类型。

java.util.ArrayList<Inter> inters = new java.util.ArrayList<Inter>();

我还有一系列重载方法,它们处理每个实现如何相互交互,以及 2 个“Inter”的默认实现。

void doSomething(Inter in1, Inter in2){
    System.out.println("Inter/Inter");     
}
void doSomething(Inter1 in1, Inter1 in2){
    System.out.println("Inter1/Inter11");    
}
void doSomething(Inter2 in1, Inter1 in2){
    System.out.println("Inter2/Inter1");    
}

像这样定期调用方法:

for(int i = 0; i < inters.size() - 1; i++){
    for(int o = i+1; o < inters.size(); o++){
        Inter in1 = inters.get(i);    Inter in2 = inters.get(o);

        doSomething(in1.getClass().cast(in1), in2.getClass().cast(in2));

        System.out.println("Class 1: " + in1.getClass().getName());
        System.out.println("Class 2: " + in2.getClass().getName());
    }
}

一个示例输出是:

Inter/Inter
Class 1: Inter
Class 2: Inter
Inter/Inter
Class 1: Inter
Class 2: Inter1
Inter/Inter
Class 1: Inter1
Class 2: Inter1

查看输出,很明显调用了 doSomething(Inter in1, Inter in2),即使在应该调用其他方法的情况下也是如此。有趣的是,输出的类名是正确的。

在运行时使用反射确定类类型时,为什么java会有静态方法重载? 有没有办法让 Java 做到这一点?我知道我可以使用反射和 Class.getMethod() 和 method.invoke() 来获得我想要的结果,但如果使用强制转换会更整洁。

我意识到之前有人提出过关于类似概念的问题,但尽管所有答案都提供了信息,但没有一个让我满意。 双重分派(dispatch)看起来可行,但这意味着需要重新编写大量代码,因为我经常使用这种类型的东西。

最佳答案

在我看来,我们正在谈论正在发生的事情:

doSomething(in1.getClass().cast(in1), in2.getClass().cast(in2));

根据您的惊讶,输出的类型始终是 Inter ,看来你对这里发生的事情有点困惑。特别是,您似乎认为 in1.getClass().cast(in1)in2.getClass().cast(in2)由于它们不同的运行时类型,应该强制使用不同的重载。然而,这是错误的。

方法重载解析是静态发生的。这意味着它是基于方法的两个参数的声明类型而发生的。由于两者 in1in2都声明为 Inter ,选择的方法显然是void doSomething(Inter in1, Inter in2) .

这里的要点是 in1被声明为 Inter .这意味着 in1.getClass()本质上与 Inter.class 相同出于静态分析的目的——getClass简单地返回一个 Class<? extends Inter> .因此,转换是无用的,您只会得到第一个重载。

关于java - Java 中的反射转换和重载方法调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9900634/

相关文章:

java - 如何在 JLabel 中的文本前添加空格?

java - Gradle 中的并行执行

java - Google Places api AutocompletePrediction prediction.getDescription() MissingAfter 升级到 Play 服务到 9.4.0

java - MyBatis 映射器通过反射插入注释

Java 泛型反射 : Generic field type of subclass

Java 将属性和值附加到现有 XML

c# - 在 C# 中使用反射获取嵌套对象的属性

c++ - 重载调用不明确

c++ - 主发生器溢出? C++

generics - Kotlin 编译器的类型推断无法选择调用哪个方法(泛型有歧义)