【问题标题】:Can two Java methods have same name with different return types? [duplicate]两个 Java 方法可以同名但返回类型不同吗? [复制]
【发布时间】:2011-07-30 12:08:51
【问题描述】:

两个 Java 方法可以具有相同的名称和不同的返回类型吗?方法的返回类型不同,声明的方法名称相同。

允许吗?

【问题讨论】:

  • 如果类是相同的,并且当且仅当两个方法具有不同的参数,那么只有它是可能的。
  • @Aleadam - 这有关系吗? OP 要求提供信息……而不是代码。
  • @Stephen 是的,但是很容易找到可以在任何书籍的第一章中找到的信息,这就是我问的原因。
  • 你是想说相同的签名还是只是方法名称?这有很大的不同
  • @Aleadam - 我不遵循你的推理。您是说如果是家庭作业,OP 需要在书中查找答案吗? (否则不是?)如果不是,你的问题有什么相关性?

标签: java methods return-type


【解决方案1】:

如果两个方法的参数类型相同,但返回类型不同,这是不可能的。来自Java Language Specification, Java SE 8 Edition, §8.4.2. Method Signature:

如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为M的类型参数,形式参数类型相同。

如果两种方法都有不同的参数类型(因此,它们有不同的签名),那么这是可能的。这叫做重载。

【讨论】:

  • +1 用于链接到规范......并且正确清晰。
  • 但这为什么会有用呢?
【解决方案2】:

仅当它们接受不同的参数时。如果没有参数,那么你必须有不同的名字。

int doSomething(String s);
String doSomething(int); // this is fine


int doSomething(String s);
String doSomething(String s); // this is not

【讨论】:

  • 不仅如此。 int doSomething(string) 和 String doSomething(String) 有不同的返回类型,所以 Java Bytecode 中的签名也是不同的,所以是允许的。要调用此方法,必须使用反射或字节码。
  • @barwnikk:当然,但是返回类型与它没有任何关系——由于大小写不同,它们也有不同的名称。
  • 大小写不同,因为我的 shift 键坏了。 ;) 您可以创建两个具有相同参数和方法名称的方法,但只有不同的返回值。但是你会在 Eclipse 中遇到问题。当你调用方法时,你会得到错误,所以你必须使用字节码。 ;) 很多混淆器都在使用它。类名可以是“if”、“do”、“for”,如果你知道字节码的话。
【解决方案3】:

但是,根据 JLS,由于 Java 6/7 编译器(Oracle 的 JDK、OpenJDK、IBM 的 JDK)中的功能/错误,如果您使用泛型,您不能为相同的方法签名具有不同的返回类型。

public class Main {
    public static void main(String... args) {
        Main.<Integer>print();
        Main.<Short>print();
        Main.<Byte>print();
        Main.<Void>print();
    }

    public static <T extends Integer> int print() {
        System.out.println("here - Integer");
        return 0;
    }
    public static <T extends Short> short print() {
        System.out.println("here - Short");
        return 0;
    }
    public static <T extends Byte> byte print() {
        System.out.println("here - Byte");
        return 0;
    }
    public static <T extends Void> void print() {
        System.out.println("here - Void");
    }
}

打印

here - Integer
here - Short
here - Byte
here - Void

更多详情,read my article here

【讨论】:

  • JLS 确实允许这 4 种方法,即使它们具有相同的返回类型。实际上在讨论重载时根本不考虑返回类型(#8.4.2)。因此,根据当前的语言规范,允许这 4 种方法不是错误。但是,如果它们具有相同的返回类型,则 javac 无法编译它们 - is 是一个错误。错误是语言规范;他们没有仔细考虑整个泛型问题。
  • @irreputable,同意泛型,这就是为什么我认为延迟关闭可能是一件好事,如果这意味着设计经过深思熟虑。 ;) 看看你必须做什么来创建一个泛型数组,或者使用双重和三重强制转换,或者即使java.util.ArrayList 也不会在没有警告的情况下编译(必须是最基本的用例)
【解决方案4】:

没有。 C++ 和 Java 都不允许对函数的返回类型进行重载。原因是返回类型的重载可能会令人困惑(开发人员很难预测将调用哪个重载)。事实上,有些人认为任何重载都会在这方面造成混淆并建议反对,但即使是那些支持重载的人似乎也同意这种特殊形式过于混乱。

【讨论】:

  • 在Java中(至少)两个方法可以具有相同的名称和不同的返回类型只要它们也有不同的参数类型;请参阅@uthark 的答案链接的 JLS 部分。
  • 对,但这不是返回类型的重载,而是参数类型的重载。而且重载恰好有不同的返回类型(返回类型与重载完全无关)。
【解决方案5】:

只有当其中一个方法被继承并且返回类型兼容时,您才能拥有两个具有相同参数和不同返回类型的方法。

例如:

public class A
{
    Object foo() { return null; }
}

public class B
    extends A
{
    String foo() { return null; }
}

【讨论】:

  • 没错,我今天早些时候才发现这一点。如果你打电话给B.class.getDeclaredMethods(),你会看到他们两个都出现了。您可以通过反射调用任一版本。
【解决方案6】:

java 文档说明:

编译器在区分方法时不考虑返回类型,因此即使返回类型不同,也不能声明两个签名相同的方法。

见:http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

【讨论】:

    【解决方案7】:

    即使是老话题,也可能有人感兴趣。

    如果您可以选择在同一个类中使用 same 方法并归档不同的返回类型,请使用泛型:Oracle Lesson Generics

    通用值持有者类的简单示例:

    class GenericValue<T> {
      private T myValue;
    
      public GenericValue(T myValue) { this.myValue = myValue; }
    
      public T getVal() { return myValue; }
    }
    

    并像这样使用它:

    public class ExampleGenericValue {
      public static void main(String[] args) {
        GenericValue<Integer> intVal = new GenericValue<Integer>(10);
        GenericValue<String> strVal = new GenericValue<String>("go on ...");
    
        System.out.format("I: %d\nS: %s\n", intVal.getVal(), strVal.getVal());
      }
    }
    

    ... 将产生以下输出:

    I: 10
    S: go on ...
    

    【讨论】:

      【解决方案8】:

      仅当它们的参数声明与内存不同时。

      【讨论】:

        【解决方案9】:

        如果它在同一个类中,具有相同类型和顺序的相同数量的参数, 那么这是不可能的,例如:

        int methoda(String a,int b) {
                return b;
        }
        String methoda(String b,int c) {
                return b;    
        }
        

        如果参数的数量和它们的类型相同,但顺序不同,那么这是可能的,因为它会导致方法重载。这意味着方法签名是否相同,包括方法名称、参数数量及其类型以及定义的顺序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多