为什么我在Java中得到关于实用程序类的警告

我正在学习Java和OOPS,并在Eclipse中编程一个基本的Hello World时,看到一个黄色的三angular形,告诉我“实用程序类不应该有公共或默认的构造函数” 。 我无法理解为什么会发生这种情况,这是什么意思? 我在做什么不对?

class HelloWorld { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("Hola Mundo!"); } } 

编辑1:编辑代码以包含build议的更改。

 final class HelloWorld { private HelloWorld() { throw new AssertionError("Instantiating utility class..."); } public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("Hola Mundo!"); } } 

仍然收到线路类HelloWorld的警报。

EDIT2:

创build一个新的类,现在它的作品。 谢谢乔恩,老class为什么还要警告呢? 波西米亚我还没有意识到你在文章中提到的概念。 一旦我有了一个更好的主意,我会回到他们身边。 谢谢你解释的事情。

这意味着有人可以写:

 HelloWorld helloWorld = new HelloWorld(); 

当你可能不希望他们 – 你没有提供任何实例成员,那么为什么让他们创build实例? 重写你的代码为:

 final class HelloWorld { private HelloWorld() { // Prevent instantiation // Optional: throw an exception eg AssertionError // if this ever *is* called } public static void main(String[] args) { System.out.println("Hola Mundo!"); } } 

Jon说了什么,但是你也应该知道每个class级都有一个构造函数,无论你是否声明一个。 如果你没有声明一个,那么默认的构造函数就是为你定义的。

换句话说,这两个类在行为上是相同的:

 public class ClassA { } public class ClassB { public ClassB() { } } 

注意:有一个私人的构造函数不会阻止实例化!

而只是为了肛门,有一个私人的构造函数不会阻止某人实例化你的类,它只是让它更难:

有(至less)两种方式来解决它:

声明一个工厂方法(很明显,但是如果这是你公司的代码,有人可以这样做):

 public class ClassA { private ClassA() {} public static ClassA create() { return new ClassA(); // oops! this one got away } } 

使用reflection(鬼鬼祟祟的,似乎错了,但它的工作原理!):

 public class ClassA { private ClassA() {} } // Elsewhere, in another class across town: Constructor<?> constructor = ClassA.class.getDeclaredConstructor(); // constructor private? no problem... just make it not private! constructor.setAccessible(true); // muhahahaha Object obj = constructor.newInstance(); System.out.println(obj.getClass().getSimpleName()); // Prints ClassA! 

保证没有人创build实例的唯一方法是在一个(也可以使它私有)构造函数中抛出一个exception。

为了保持完整性,迄今没有任何回应者对原来的课程有其他问题进行评论

 class HelloWorld { 

正如所暗示的那样,你变成了

 final class HelloWorld { 

Java类的final关键字禁止其他类扩展(inheritance)。 如果你没有做出最终的类,扩展类可以使用你可能没有想到的各种东西,因为扩展类可以访问inheritance类的protected成员。

总是让你的课既是abstract ,也是final ,这是好的做法,这意味着他们只是为了或不是为了inheritance。 当你devise一个类可以实例化(不是抽象的)和可扩展的(不是最终的)时,会有很多次,但是做出这个有意识的决定是一个很好的习惯。

写一个实用程序类最简单的方法是你有没有实例的枚举。 你可以用Java 5.0或更高版本来完成。

 public enum Utility {; public static void main(String... args) { System.out.println("Hola Mundo!"); } } 

您不必定义私有构造函数,也不能使用内部类或reflection等其他技巧创build实例。 (如果您忽略不安全的类;)

顺便说一句:有些人看到使用enum作为黑客,但对我来说明确地说:“我有一个没有实例的类”,而不是防止创build间接的实例。

看看这个: http : //checkstyle.sourceforge.net/config_design.html#HideUtilityClassConstructor
我假设你正在使用CheckStyle。