java utility 是什么_关于java:Helper / Utility类应该抽象吗?

我通常会发现自己将类的常见行为提取到帮助程序/实用程序类中,该类只包含一组静态方法。 我经常想知道是否应该将这些类声明为抽象类,因为我真的想不出实例化这些类的有效理由吗?

将这样的类声明为抽象将是什么利弊。

public [abstract] class Utilities{

public static String getSomeData(){

return"someData";

}

public static void doSomethingToObject(Object arg0){

}

}

您可以声明一个不执行任何操作的私有构造函数。

声明类"抽象"的问题在于abstract关键字通常意味着该类打算被子类化和扩展。那绝对不是你想要的。

并可能将其声明为最终声明,以使您的意图绝对清晰。

可悲的是,您不能将其声明为抽象的final。 :-)

他没有暗示他应该...:|

不要打扰让它们成为抽象,而是包括一个私有的无参数构造函数,以防止它们被实例化。

感兴趣的人的比较点:在C#中,您将声明该类为静态类,使其以编译形式抽象和密封(Java的最终版本),并且完全没有任何实例构造函数。这也使得声明该类型的参数,变量,数组等成为编译时错误。便利。

我没有将实用程序类声明为抽象,而是将它们声明为final并使构造函数私有。这样,它们就不能被子类化,也不能被实例化。

public final class Utility

{

private Utility(){}

public static void doSomethingUseful()

{

...

}

}

使用上面建议的这种格式,我是否应该使用"静态导入"行来导入要在我的项目中使用的类方法?

我将在私有构造函数之外添加更多步骤:

public class Foo {

// non-instantiable class

private Foo() { throw new AssertionError(); }

}

抛出AssertionError可以防止同一类中的方法实例化该类(可以尝试)。这通常不是问题,但是在团队环境中,您永远都不知道有人会做什么。

关于"抽象"关键字,我注意到在许多情况下子类化的实用程序类:

public class CoreUtils { ... }

public class WebUtils extends CoreUtils { ... }

public class Foo { ... WebUtils.someMethodInCoreUtils() ... }

我相信这样做是为了使人们不必记住要包括哪个实用程序类。这有什么缺点吗?这是反模式吗?

问候,

莱斯

通过将它们声明为抽象,实际上是在向其他编码器指示您打算从中继承这些类。确实,您是对的,没有太大的区别,但是这里的语义实际上更多地是关于其他查看您的代码的人的解释。

如其他人所述,创建一个私有的无参数构造函数。除了类本身之外,没有人可以创建它的实例。

正如其他人展示了如何用其他语言完成操作一样,下面是您在下一个C ++版本中的操作方法,以及如何使类不可实例化的方法:

struct Utility {

static void doSomething() { /* ... */ }

Utility() = delete;

};

我认为最好使用私有的无参数构造函数将实用程序类声明为final。此外,此类的所有成员都应该是静态的。

在一个语句中完成所有这些操作的一种简单方法是使用Lombok的@UtilityClass批注:

@UtilityClass

public class Utilities{

public String getSomeData() {

return"someData";

}

public void doSomethingToObject(Object arg0) {

}

}

如果使用@UtilityClass批注,则可以跳过上面的示例中的静态关键字,因为Lombok在编译过程中会自动添加它们。

我可以提供一些建设性的建议吗?

如果您要执行很多操作,则会遇到两个问题。

首先,带有参数的静态方法通常应该是该参数的对象的一部分。我意识到这对像String这样的对象没有帮助,但是如果它接受您已定义的对象,则几乎可以肯定的是,可以通过将助手作为该对象的方法包括在内来改进该对象。

如果它采用所有本机值,则可能可以定义一个作为其方法的对象。看看是否可以找到这些原始值的任何分组并将它们分组为一个对象。如果您只是尝试一下,您会发现该小物件还有很多其他用途,并且在您不知道它会非常有用的情况下。

另一件事,如果您有一个带有一堆半相关的静态方法和静态变量的实用程序类,则几乎总是希望它成为单例。我通过反复试验发现了这一点,但是当您发现需要多个(最终会需要)时,将单例转换为multipleton(?),然后尝试将静态类更改为multipleton((好的,所以我现在要说些什么)。

祝好运。这些东西对我来说大多是试验和错误的-尽管将它弄成5年前的样子,但我从未发现我后悔没有静态类/方法的实例。

有人提到在C#3.0中,您可以通过扩展方法来完成此任务。我不是C#的人,在1.5 / 2.0天内做了一些工作,但是从那时起就没有使用过。基于非常粗略的理解,我认为使用静态导入在Java中可以完成类似的操作。我意识到它根本不是一回事,但是如果目标是使这些实用程序方法对调用类来说看起来更"本机"(因为缺少更好的术语),我认为它将成功。假设我在原始问题中声明了Utilities类。

import static Utilities.getSomeData;

public class Consumer {

public void doSomething(){

String data =  getSomeData();

}

}

这是有效的Java吗?

Helper / Utility方法很好。不必担心将它们添加到应用程序或Framework内部的库中。我见过的大多数框架都在许多方面使用它们。

话虽如此,如果您想真正地对它们有所了解,就应该研究C#3.0中的扩展方法。使用扩展方法将使您的实用程序更像是框架的"整体"部分,这似乎是您正在考虑通过使其抽象化来尝试做的事情。更不用说扩展方法了,写起来很有趣!

不,但是如果您的语言支持,则有一个很强的论点,即在大多数情况下,它们应该(可以)声明为"静态" ...静态告诉编译器无法实例化它们,并且其中的所有方法必须是静态的。

抽象用于确实具有基于实例的实现细节的类,派生类的实例将使用这些细节...

java类不能声明为静态,可以吗? 也许我只是误解了您的观点?

抱歉,Im .Net家伙...并没有注意到java标记...然后,如果无法将java类声明为静态,则应将私有无参数ctor设置为静态,并将所有成员设置为静态...

在某些情况下,可以将Java类声明为静态类,但这意味着有所不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值