简体   繁体   English

Class类中的getDeclaredMethods()

[英]getDeclaredMethods() in Class class

public Method[] getDeclaredMethods() throws SecurityException

has documentation as below. 有如下文件。

/**
     *
     * Returns an array containing {@code Method} objects reflecting all the
     * declared methods of the class or interface represented by this {@code
     * Class} object, including public, protected, default (package)
     * access, and private methods, but excluding inherited methods.

<p> If this {@code Class} object represents a type that has multiple
             * declared methods with the same name and parameter types, but different
             * return types, then the returned array has a {@code Method} object for
             * each such method.
         *

how can a single class have two [declared] methods with different return types, same name and same parameter types? 单个类如何具有两个具有不同返回类型,相同名称和相同参数类型的[声明]方法?

It's not possible in the Java language to declare two methods with same names and parameter types but different return types. Java语言中 ,不可能声明两个具有相同名称和参数类型但返回类型不同的方法。

The Java Virtual Machine (JVM) however has no problem handling methods like that. 然而,Java虚拟机(JVM)处理方法没有问题。

There is a way to create such methods implicitly, by overriding a base class method with a more specific return type. 有一种方法可以通过使用更具体的返回类型覆盖基类方法来隐式创建此类方法。

If a base class has a method Object foo() and your class overrides it with a method String foo() then the .class file of your class will have a synthetic (and thus not "visible") method Object foo() and a "normal" method String foo() . 如果一个基类有一个方法Object foo() ,你的类用一个方法String foo()覆盖它,那么你的类的.class文件将有一个合成的(因此不是“可见的”)方法Object foo()和“normal”方法String foo() The Object foo() method exists for compatibility with classes that want to treat your class as an instance of the base class and don't know about the String foo() override. Object foo()方法的存在是为了与想要将您的类视为基类的实例并且不知道String foo()重写的类兼容。

Additionally some non-Java languages might let you create classes with those kinds of method explicitly. 此外,一些非Java语言可能允许您显式地使用这些方法创建类。

A simple example: 一个简单的例子:

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

public class MultipleMethods implements Callable<String> {
    public static void main(String[] args) {
        for(Method m: MultipleMethods.class.getDeclaredMethods()) {
            System.out.println(m);
        }
    }

    @Override
    public String call() {
        return "just an example";
    }
}

Test on ideone.com 在ideone.com上测试

public static void MultipleMethods.main(java.lang.String[])
public java.lang.Object MultipleMethods.call() throws java.lang.Exception
public java.lang.String MultipleMethods.call()

Due to type erasure , the interface Callable has a method java.lang.Object call() and code trying to invoke that method will look for exactly that method only, therefore, a so-called bridge method has been inserted to fulfill the protocol and delegate to the actual implementation method String call() . 由于类型擦除Callable接口有一个方法java.lang.Object call()和试图调用该方法的代码只会查找该方法,因此,插入了一个所谓的桥接方法来实现协议和委托给实际的实现方法String call() You can identify bridge methods via Method.isBridge() . 您可以通过Method.isBridge()识别桥接方法。

The same kind of bridge methods are created when using covariant return types without Generics, as described by this answer . 当使用没有泛型的协变返回类型时,会创建相同类型的桥接方法,如本答案所述 Also, as already said by this answer, class files could have been created by other means than Java source code and since the JVM can handle methods only differing in return type, such methods could appear in such classes without having bridge semantics. 此外,正如本答案所述,类文件可能是通过Java源代码之外的其他方式创建的,并且由于JVM可以处理仅在返回类型方面不同的方法,因此这些方法可以出现在这些类中而不具有桥接语义。

By the way, on the bytecode level, even declared fields are distinguished by name and type, thus, do not need to have unique names if they differ in type. 顺便说一下,在字节码级别上,即使声明的字段也按名称类型进行区分,因此,如果它们的类型不同,则不需要具有唯一的名称。 There is no way to generate class files with declared fields of the same name with Java source code, but, as said, that's not the only way to create class files. 没有办法使用Java源代码生成具有相同名称的声明字段的类文件,但是,如上所述,这不是创建类文件的唯一方法。

You are probably confusing getDeclaredMethod() : Method vs getDeclaredMethods() : Method[] or privateGetDeclaredMethods() : Method[] , that have a different name. 您可能会混淆getDeclaredMethod() : Method vs getDeclaredMethods() : Method[]privateGetDeclaredMethods() : Method[] ,它们具有不同的名称。

However you can have methods with the same name, same return type but different parameters. 但是,您可以使用相同名称,相同返回类型但参数不同的方法。 This is possible because of method overloading in Java. 这是可能的,因为Java中的方法重载


For simplicity, this is a very legal piece of code: 为简单起见,这是一段非常合法的代码:

public class Test {
    public int get(int a) {
        return a;
    }

    public int get() {
        return 0;
    }
}

This isn't: 这不是:

public class Test {
    public int get() {
        return 0;
    }

    public long get() {
        return 0;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM