在Java中,是不是可以有两个具有完全相同签名的函数,除了一个是静态的
Posted
技术标签:
【中文标题】在Java中,是不是可以有两个具有完全相同签名的函数,除了一个是静态的【英文标题】:In Java, Is it Possible to Have Two Functions with the Exact Same Signature, Except One is static在Java中,是否可以有两个具有完全相同签名的函数,除了一个是静态的 【发布时间】:2021-12-14 00:01:01 【问题描述】:我正在编写一个类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>
,或者我的数据类型使用:
方法 my-method-signature 的擦除与 my-class-name 类型中的另一个方法相同
问题:
-
还有比我正在尝试或想要做的更好的选择吗?是否有可能完成我正在尝试的事情?如果有,怎么做?
我正在尝试做的事情(即,使语法一致,并且不可能调用具有“不匹配”
SomeClass1<T>
和 this
对象的方法)是否值得?
附:抱歉,帖子太长了。
【问题讨论】:
你为什么担心将静态方法设为可以是静态的?为什么不让它保持非静态并继续前进? 此链接可能会有所帮助:***.com/questions/42185449/…。另请注意,在某些情况下,使用static
方法通常是一种反模式。尽量让事情变得简单。
我觉得你的问题相当混乱。有一次你说你想阻止baz2.foo(new Bar(), sc);
,然后你继续尝试将both声明为非静态和静态foo
,这根本不会阻止......
@Sweeper 我试图通过提供替代选项来防止这种情况,但仍与其他语法保持一致。写这个的时候还不知道可以用对象调用静态函数。
【参考方案1】:
是的,有一个更好的选择:什么都不做。
拥有不需要this
来完成工作的方法并没有错。这是一种实现选择,与实例履行其实现方法的约定无关。
有很多常用的设计模式都有这样的方法。以各种工厂模式为例——它们的方法有一个返回实例的契约。没有人知道或关心他们是否使用this
来完成工作。
【讨论】:
【参考方案2】:不,你不能。
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.html#jls-8.4
【讨论】:
以上是关于在Java中,是不是可以有两个具有完全相同签名的函数,除了一个是静态的的主要内容,如果未能解决你的问题,请参考以下文章