允许特定类的实例仅由Java中的另一个类创建?

允许特定类的实例仅由Java中的另一个类创建?,java,singleton,access-modifiers,Java,Singleton,Access Modifiers,假设我有两个类A和B,我想使B的实例只能在A和B本身中创建。我不希望允许任何其他类(包括A的子类)创建B的实例。在Java中有什么方法可以做到这一点吗 如果不清楚我想做什么,这里有一些代码: public class A { B instance; public A(){ // Still allows for subclasses to access B instance = B.getInstance((Object)this); }

假设我有两个类A和B,我想使B的实例只能在A和B本身中创建。我不希望允许任何其他类(包括A的子类)创建B的实例。在Java中有什么方法可以做到这一点吗

如果不清楚我想做什么,这里有一些代码:

public class A {
    B instance;
    public A(){
        // Still allows for subclasses to access B
        instance = B.getInstance((Object)this);
    }
}
下面是我要限制其构造的类:

public class B {

    // If I make this public all classes can create it, but
    // if I make it private without any getter methods then
    // no other classes but itself can create it
    private B(){}

    // Problem with this is that subclasses of  A
    // can also create instances of B
    public static B getInstance(Object o){
        if(o instanceof A)
            return new B();
        else
            return null;
    } 
}
我曾尝试在StackOverflow上搜索可能的解决方案,但我发现最接近的一点是使用带有修改过的getInstance()方法的Singleton设计模式,以确保只有具有特定类型的类才能访问类B的实例。虽然这很有效,它仍然允许任何扩展A的子类获得B的实例。有没有办法阻止这种情况发生,或者如果一个子类不能完成它的超类所能完成的任务,它会破坏整个子类化过程

假设我有两个类A和B,我想使B的实例只能在A和B本身中创建。我不希望允许任何其他类(包括A的子类)创建B的实例

你们可以使B成为一个类的私有内部类

虽然这工作得相当好,但它仍然支持 扩展A以获取B的实例。是否有任何方法阻止此操作 如果 子类不能做它的超类能做的事情

如果您不希望类A被子类化,可以将类A设为final,或者可以为类A设置一个私有构造函数。尽管如前面的答案所建议的那样,创建私有内部类更好

public final class A {
    B instance;
    public A(){
        // Still allows for subclasses to access B
        instance = B.getInstance((Object)this);
    }
}

如果创建的类不是B类,则该类将引发异常

class A {

    A() {
        new SecurityManager() {
            {
                if (getClassContext()[1] != B.class) {
                    throw new IllegalStateException();
                }
            }
        };
    }
...

你不能用反射来打破它

A
可以向
B
呈现只有
A
才能拥有的东西。比如说

public class A
{
    public static class Pass
    {
        private Pass(){}
只有
A
可以创建
A.Pass
对象。如果这样的对象只从
A
传输到
B
,那么没有其他人能够抓住它们并假装成
A

public class B
{
    public static B getInstance(A.Pass token)
    {
        if(pass==null) 
            throw ...      
        else
            caller must be A

虽然另一个答案稍微好一点,但对于我的特定应用程序,我实际上不需要首先创建A的子类,所以这很有用。另外,如果我想将一个冗长的私有内部类移动到它自己的独立源文件中以便于可读,这可能会有所帮助。因此+1.虽然我认为条件必须是getClassContext()[2]!=B.class,因为getClassContext()[1]为您提供了一个.class,getClassContext()[0]为您提供了SecurityManager类。该类是否可能不是内部的,而是与主类在同一个包中,但仍然可以像内部类一样创建?