Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:只允许一个类实例化_Java_Constructor - Fatal编程技术网

Java:只允许一个类实例化

Java:只允许一个类实例化,java,constructor,Java,Constructor,我希望我的项目中的某些类被合并。因此,我不希望能够使用:new SomeClass()实例化这些类,而是使用SomeClass.allocate()从池中获取一个新项。 对于每个需要池的类,我都有这样的代码 public class GameObject { // Pooling: Provides a static method for allocation and a method for freeing private static Pool<GameObject&g

我希望我的项目中的某些类被合并。因此,我不希望能够使用:new SomeClass()实例化这些类,而是使用SomeClass.allocate()从池中获取一个新项。 对于每个需要池的类,我都有这样的代码

public class GameObject
{
    // Pooling: Provides a static method for allocation and a method for freeing
    private static Pool<GameObject> pool = new Pool<GameObject>();
    public static GameObject allocate() { return pool.obtain(); }
    public void free() { pool.free(this); }
    ...
}
公共类游戏对象
{
//池:提供静态分配方法和释放方法
私有静态池=新池();
公共静态游戏对象分配(){return pool.get();}
public void free(){pool.free(this);}
...
}
现在,我可以通过将默认构造函数设置为私有来禁用正常的实例化方式,但问题是池需要在创建类时实例化类,以及在池需要扩展时实例化类


有没有办法将构造限制为仅由池进行?

我可以看到两个选项:要么将其设置为池的内部类,要么将
allocate
方法包设置为私有,并将其与池放在同一个包中

编辑:啊。只需将构造函数设置为私有,然后覆盖
池使用的任何方法来创建新实例。作为使用上述框架的(粗略)示例:

public abstract class Pool<T>
{
    public abstract T getNewObject();

    public T obtain(){ return getNewObject(); }

    public void free(T obj) {}
}
公共抽象类池
{
公共抽象T getNewObject();
public T get(){return getNewObject();}
公共无效自由(T obj){}
}

公共类游戏对象
{
//池:提供静态分配方法和释放方法
私有静态池=新池(){
公共游戏对象getNewObject(){返回新游戏对象();}
};
公共静态游戏对象分配(){return pool.get();}
私有游戏对象(){}
public void free(){pool.free(this);}
}

GameObject
的构造器对于其他任何人来说都是不可访问的。

作为最后手段,您可以使用反射。对于其他选择,其他人已经告诉了。 我记得Spring容器能够初始化具有私有构造函数的类。我对此感到惊讶。我猜它也使用了这个技巧。好处可能是它更通用

public static void main(String... args) {
    try {
      Constructor c = GameObject.class.getDeclaredConstructor();
      c.setAccessible(true); // solution
      c.newInstance();

      // production code should handle these exceptions more gracefully
    } catch (InvocationTargetException x) {
      x.printStackTrace();
    } catch (NoSuchMethodException x) {
      x.printStackTrace();
    } catch (InstantiationException x) {
      x.printStackTrace();
    } catch (IllegalAccessException x) {
      x.printStackTrace();
    }
  }

备选方案:不要试图让你的代码跳转。使用静态分析来强制执行这样的规则。如果你不小心做了一些你不想做的事情,工具会被捕获。< /P>你刚从C++移到java吗?因为这种事情是用C++完成的,在这个世界上有时是个好主意,但在java中可能永远都不是个好主意。我说BTW是因为传统的智慧是JVM比你做的更好。你能把代码添加到游戏中吗?Pool@Kevin不,我没有。我正在为Android开发一款游戏。Android设备上的垃圾收集器在运行时最多会阻塞数百毫秒,因此我需要避免在游戏循环中进行分配。对象池似乎是大多数其他人都在做的事情。哇,当Java垃圾收集器处于临界状态时,这真是一场灾难。我不能将其作为一个内部类,因为池是一个静态成员,而不是封闭在一个实例中。+1:您应该能够将其作为一个嵌套类(或静态内部类)如果真的有帮助,请接受我的回答。:-)非常感谢你:这真的帮了我的忙。但是顺便问一下:什么声明了我的代码是否有权限设置可访问的构造函数?一般来说,我会有点犹豫是否要用这种方式来覆盖Java的内置行为。但这确实有效。
public static void main(String... args) {
    try {
      Constructor c = GameObject.class.getDeclaredConstructor();
      c.setAccessible(true); // solution
      c.newInstance();

      // production code should handle these exceptions more gracefully
    } catch (InvocationTargetException x) {
      x.printStackTrace();
    } catch (NoSuchMethodException x) {
      x.printStackTrace();
    } catch (InstantiationException x) {
      x.printStackTrace();
    } catch (IllegalAccessException x) {
      x.printStackTrace();
    }
  }