我正在学习Java和OOPS,在eclipse中编写一个基本的Hello World时,我看到一个黄色三角形告诉我"实用程序类不应该有公共或默认构造函数".我无法理解为什么会发生这种情况,这是什么意思?我做得怎么样?
class HelloWorld {
public static void main(String[] args)
{
// TODO Auto-generated method stub
System.out.println("Hola Mundo!");
}
}
Run Code Online (Sandbox Code Playgroud)
EDIT1:编辑代码以包含建议的更改.
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!");
}
}
Run Code Online (Sandbox Code Playgroud)
仍在线上HelloWorld的警报.
EDIT2:
创建了一个新类,现在它可以工作了.谢谢Jon.为什么旧班仍然会发出警告?波希米亚人我还没有意识到你在帖子中提到的概念.一旦我有了更好的主意,我会回到他们身边.谢谢你解释一下.
Jon*_*eet 58
这意味着有人可以写:
HelloWorld helloWorld = new HelloWorld();
Run Code Online (Sandbox Code Playgroud)
如果您可能不希望它们 - 您没有提供任何实例成员,那么为什么要允许它们创建实例?将您的代码重写为:
final class HelloWorld {
private HelloWorld() {
// Prevent instantiation
// Optional: throw an exception e.g. AssertionError
// if this ever *is* called
}
public static void main(String[] args) {
System.out.println("Hola Mundo!");
}
}
Run Code Online (Sandbox Code Playgroud)
Boh*_*ian 17
Jon说了什么,但是你也应该知道每个类都有一个构造函数,无论你是否声明了一个.如果您没有声明一个,则默认为您定义"默认构造函数".
换句话说,这两个类的行为是相同的:
public class ClassA {
}
public class ClassB {
public ClassB() {
}
}
Run Code Online (Sandbox Code Playgroud)
只是为了肛门,拥有一个私有构造函数并不会阻止某人实例化你的类,它只会让它变得更难:
有(至少)两种方法来解决它:
声明一个工厂方法(很明显,但如果它是你公司的代码,有人可以这样做):
public class ClassA {
private ClassA() {}
public static ClassA create() {
return new ClassA(); // oops! this one got away
}
}
Run Code Online (Sandbox Code Playgroud)
使用反射(鬼鬼祟祟,似乎有点错误,但它有效!):
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!
Run Code Online (Sandbox Code Playgroud)
保证没有人创建实例的唯一方法是在(也可能使其成为私有)构造函数中抛出异常.
为了完整起见,到目前为止,没有一个响应者对您的原始课程的另一个问题发表评论
class HelloWorld {
Run Code Online (Sandbox Code Playgroud)
如你所说,你变成了
final class HelloWorld {
Run Code Online (Sandbox Code Playgroud)
finalJava类上的关键字禁止其他类扩展(继承)它.如果不使类成为final,则扩展类可以使用您可能没有预期的各种事物,因为扩展类可以访问protected继承类的成员.
优良作法是始终使您的类成为abstract或者final,意味着它们仅用于继承或不用于继承.很多时候你会设计一个既可以实例化(不抽象)又可扩展(不是最终)的类,但是这个有意识的决定是一个很好的习惯.
编写实用程序类的最简单方法是使用没有实例的枚举.您可以使用Java 5.0及更高版本.
public enum Utility {;
public static void main(String... args) {
System.out.println("Hola Mundo!");
}
}
Run Code Online (Sandbox Code Playgroud)
您不必定义私有构造函数,也不能使用内部类或其他技巧(如反射)创建实例.(如果忽略Unsafe类;)
顺便说一句:有些人认为使用enumhack作为黑客,但对我来说它明确地说"我有一个没有实例的类",而不是阻止创建间接的实例.
| 归档时间: |
|
| 查看次数: |
38222 次 |
| 最近记录: |