这是关于java私有构造函数的这个问题的后续内容.
假设我有以下课程:
class Foo<T>
{
private T arg;
private Foo(T t) {
// private!
this.arg = t;
}
@Override
public String toString() {
return "My argument is: " + arg;
}
}
Run Code Online (Sandbox Code Playgroud)
我如何构建new Foo("hello")使用反射?
回答
根据jtahlborn的回答,以下作品:
public class Example {
public static void main(final String[] args) throws Exception {
Constructor<Foo> constructor;
constructor = Foo.class.getDeclaredConstructor(Object.class);
constructor.setAccessible(true);
Foo<String> foo = constructor.newInstance("arg1");
System.out.println(foo);
}
}
Run Code Online (Sandbox Code Playgroud) 在java中创建单例类的最佳/正确方法是什么?
我发现的一个实现是使用私有构造函数和getInstance()方法.
package singleton;
public class Singleton {
private static Singleton me;
private Singleton() {
}
public static Singleton getInstance() {
if (me == null) {
me = new Singleton();
}
return me;
}
}
Run Code Online (Sandbox Code Playgroud)
但是在以下测试用例中实现失败了
package singleton;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test {
/**
* @param args
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
InstantiationException, IllegalAccessException, …Run Code Online (Sandbox Code Playgroud) 您知道,自Java 5发布以来,在Java中编写Singleton模式的推荐方法是使用枚举.
public enum Singleton {
INSTANCE;
}
Run Code Online (Sandbox Code Playgroud)
但是,我不喜欢这个 - 是强制客户端使用Singleton.INSTANCE来访问单例实例.也许,更好的方法是在普通类中隐藏Singleton,并提供更好的单例设施访问:
public class ApplicationSingleton {
private static enum Singleton {
INSTANCE;
private ResourceBundle bundle;
private Singleton() {
System.out.println("Singleton instance is created: " +
System.currentTimeMillis());
bundle = ResourceBundle.getBundle("application");
}
private ResourceBundle getResourceBundle() {
return bundle;
}
private String getResourceAsString(String name) {
return bundle.getString(name);
}
};
private ApplicationSingleton() {}
public static ResourceBundle getResourceBundle() {
return Singleton.INSTANCE.getResourceBundle();
}
public static String getResourceAsString(String name) {
return Singleton.INSTANCE.getResourceAsString(name);
}
}
Run Code Online (Sandbox Code Playgroud)
所以,客户现在可以简单地写:
ApplicationSingleton.getResourceAsString("application.name")
Run Code Online (Sandbox Code Playgroud)
例如.哪个好多了:
Singleton.INSTANCE.getResourceAsString("application.name")
Run Code Online (Sandbox Code Playgroud)
所以,问题是:这是正确的方法吗?此代码是否有任何问题(线程安全?)?它具有"enum …