一个类中有多个具有相同参数类型的方法 [英] More than one method with the same parameter types in a class

查看:59
本文介绍了一个类中有多个具有相同参数类型的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,至少已经有 关于这个主题的一个问题.但我想再问一次,因为这是我在 Class#getDeclaredMethod(...) 的javadoc:

I know, there is already at least one question on this topic. But I want to ask it again because this is what I discovered in the javadoc of Class#getDeclaredMethod(...):

如果在一个函数中声明了多个具有相同参数类型的方法类,并且这些方法之一的返回类型更多比任何其他方法都特定,返回该方法;除此以外任意选择其中一种方法.

If more than one method with the same parameter types is declared in a class, and one of these methods has a return type that is more specific than any of the others, that method is returned; otherwise one of the methods is chosen arbitrarily.

所以java中反射的开发者认为这种情况是可能的,毕竟有可能做这样的声明吗?或者它可能只是被弃用了?

So the developers of the reflection in java consider that case as a probable one, is it maybe possible after all to do such declaration? Or is it maybe just deprecated?

推荐答案

JVM 字节码格式允许声明多个具有相同名称和相同参数类型的方法,只要返回类型不同,尽管 Java 语言不允许这样做.这意味着 a) 其他 JVM 语言可以使用它,并且 b) 它可以用于特殊的编译器魔术"语言功能.

The JVM bytecode format permits the declaration of multiple methods with the same name and the same parameter types as long as the return type differs, although the Java language does not permit this. This means a) other JVM languages can make use of this and b) it can be used for special "compiler-magic" language features.

最常见的是,编译器在处理泛型时会发出多个具有相同名称和相同参数类型的方法.JVM 方法查找依赖于整个签名进行匹配,而不仅仅是参数类型.因此,编译器必须发出所谓的 bridge 方法来覆盖或隐藏其他方法签名.考虑这个例子:

Most commonly, the compiler emits multiple methods with the same name and the same parameter types when dealing with generics. JVM method lookup relies on the entire signature to match, not just the parameter types. Thus, the compiler has to emit so-called bridge methods that override or shadow other methods signature-wise. Consider this example:

interface Foo<T>
{
    T foo(); // desc: ()Ljava/lang/Object;

    void bar(T value); // desc: (Ljava/lang/Object;)V

    Object baz(); // desc: ()Ljava/lang/Object;
}

class StringFoo implements Foo<String>
{
    @Override
    public String foo() { ... } // desc: ()Ljava/lang/String; // !

    @Override
    public void bar(String value) { ... } // desc: (Ljava/lang/String;)V // !

    @Override
    public String baz() { ... } // desc: ()Ljava/lang/String; // !
}

StringFoo 类需要三个额外的桥接方法来实际覆盖具有相同desc 的接口方法:

The StringFoo class needs three additional bridge methods to actually override the interface methods in terms of having the same desc:

class StringFoo implements Foo<String>
{
    public String foo() { ... }

    public /* synthetic bridge */ Object foo() // desc: ()Ljava/lang/Object;
    {
        return /* String */ foo(); // statically linked to String foo()
    }

    public void bar(String value) { ... }

    public /* synthetic bridge */ void bar(Object value) // desc: (Ljava/lang/Object;)
    {
        return bar((String) value);
    }

    public String baz() { ... }

    public /* synthetic bridge */ Object baz() // desc: ()Ljava/lang/Object;
    {
        return /* String */ baz(); // statically linked to String baz()
    }
}

伪修饰符合成桥是两个JVM访问标志,仅供编译器用来标记字节码中自动生成的方法

The pseudo-modifiers synthetic bridge are two JVM access flags that are only used by the compiler to mark auto-generated methods in the bytecode

Class#getDeclaredMethods 方法返回所有声明的方法 - 包括合成桥接方法.因此,#getDeclaredMethod(String) 必须选择一个实际的实现.

The Class#getDeclaredMethods method returns all declared methods - including synthetic bridge methods. Thus, #getDeclaredMethod(String) has to pick one that is the actual implementation.

这篇关于一个类中有多个具有相同参数类型的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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