在 Java 中,是否可能有两个具有完全相同签名的函数,除了一个是静态的
In Java, Is it Possible to Have Two Functions with the Exact Same Signature, Except One is static
我正在编写一个 class 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
替换为相应的方法签名并将 my-class-name
替换为 Baz<T>
,或者我使用的数据类型:
Erasure of method my-method-signature is the same as another method in type my-class-name
问题:
- 有没有比我正在尝试或想要做的更好的选择?是否有可能完成我正在尝试的事情?如果可以,怎么做?
- 我正在尝试做的事情(即,使语法一致并且不可能调用具有“不匹配”
SomeClass1<T>
和 this
对象的方法)值得吗?
P.S。很抱歉 post.
是的,有一个更好的选择:什么都不做。
拥有一种不需要 this
来完成其工作的方法并没有错。这是一个实现选择,与实例履行其实现方法的契约无关。
有很多常用的设计模式都有这样的方法。以各种工厂模式为例——它们的方法与 return 实例有契约。没有人知道或关心他们是否使用 this
来完成工作。
不,你不能。
8.4.2. Method Signature Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters
(if any) (§8.4.4), and, after adapting the formal parameter types of N
to the the type parameters of M, the same formal parameter types.
The signature of a method m1 is a subsignature of the signature of a
method m2 if either:
m2 has the same signature as m1, or
the signature of m1 is the same as the erasure (§4.6) of the signature
of m2.
Two method signatures m1 and m2 are override-equivalent iff either m1
is a subsignature of m2 or m2 is a subsignature of m1.
It is a compile-time error to declare two methods with
override-equivalent signatures in a class.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4
我正在编写一个 class 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
替换为相应的方法签名并将 my-class-name
替换为 Baz<T>
,或者我使用的数据类型:
Erasure of method my-method-signature is the same as another method in type my-class-name
问题:
- 有没有比我正在尝试或想要做的更好的选择?是否有可能完成我正在尝试的事情?如果可以,怎么做?
- 我正在尝试做的事情(即,使语法一致并且不可能调用具有“不匹配”
SomeClass1<T>
和this
对象的方法)值得吗?
P.S。很抱歉 post.
是的,有一个更好的选择:什么都不做。
拥有一种不需要 this
来完成其工作的方法并没有错。这是一个实现选择,与实例履行其实现方法的契约无关。
有很多常用的设计模式都有这样的方法。以各种工厂模式为例——它们的方法与 return 实例有契约。没有人知道或关心他们是否使用 this
来完成工作。
不,你不能。
8.4.2. Method Signature Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
The signature of a method m1 is a subsignature of the signature of a method m2 if either:
m2 has the same signature as m1, or
the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.
It is a compile-time error to declare two methods with override-equivalent signatures in a class.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4