在Java中,是否可能有两个函数具有完全相同的签名,除了一个是静态的



我正在编写一个类Baz<T>,其函数声明类似于以下内容:

public SomeClass1<T> foo(T);                               // Overload #1
public SomeClass1<T> foo(T, SomeClass1<T>);                // Overload #2
public SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>); // Overload #3

因为#1是唯一使用this的函数,我可以让所有其他的static:

public SomeClass1<T> foo(T);
public static <T> SomeClass1<T> foo(T, SomeClass1<T>);             //#2 and #3 now static
public static <T> SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>);

但是,这会使调用不同的foo重载不一致。我可以简单地使#1采取Baz(而不是this),但似乎:

baz.foo(t);

更具语法糖
Baz.foo(baz, t);

如果我不把#2和#3设置为静态,那么就没有办法防止像

这样的事情发生:
Baz<Bar> baz1 = new Baz<Bar>(); // Bar is any class type; replaces T
Baz<Bar> baz2 = new Baz<Bar>();
SomeClass1<Bar> sc = new SomeClass1<Bar>(baz1); // make a SomeClass1 that is somehow attached to baz1; however, SomeClass1 does NOT keep a reference to baz1
baz2.foo(new Bar(), sc); // runs and compiles just fine!

我最终尝试做的是为每个重载设置一个非静态重载和一个静态重载,其中非静态重载简单地委托给静态重载:

public SomeClass1<T> foo(T);                 // All non-static overloads delegate to the corresponding static overload
public SomeClass1<T> foo(T, SomeClass1<T>);             
public SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>);
public static <T> SomeClass1<T> foo(T, Baz<T>);     // Baz could be first or last argument
public static <T> SomeClass1<T> foo(T, SomeClass1<T>);            
public static <T> SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>);

我得到以下错误来自重载#2,#3的声明,以及它们相应的静态重载,用相应的方法签名替换my-method-signature,用Baz<T>替换my-class-name,或者我使用的数据类型:

方法my-method-signature的擦除与类型my-class-name

中的另一个方法相同

问题:

  1. 还有比我正在尝试或想要做的更好的选择吗?有可能完成我正在尝试的事情吗?如果有,怎么做?
  2. 是我想做的(即,使语法一致,使它不可能调用一个方法与"不匹配";SomeClass1<T>this对象)甚至值得吗?

注:很抱歉写了这么长时间。

是的,有一个更好的选择:什么都不做。

拥有一个不需要this来完成其工作的方法并没有错。这是一个实现选择,它与实例是否履行实现方法的契约无关。

有很多常用的设计模式都有这样的方法。以各种工厂模式为例——它们的方法有一个返回实例的契约。没有人知道或关心他们是否使用this来完成工作。

不行。

8.4.2。如果两个方法或构造函数M和N具有相同的名称和类型参数,则它们具有相同的签名(如果有的话)(§8.4.4),并且,在适应N的形式参数类型之后对于M的类型参数,形式参数类型相同。

方法m1的签名是a的签名的子签名方法m2

m2具有与m1相同的签名,或者

m1的签名与该签名的擦除(第4.6节)相同平方米。

两个方法签名m1和m2对m1中的任何一个都是覆盖等效的是m2的子签名或者m2是m1的子签名

声明两个方法是编译时错误覆盖类中的等价签名。

https://docs.oracle.com/javase/specs/jls/se8/html/jls 8. - 8.4 # jls - html

相关内容

最新更新