Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.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_Android_Kotlin - Fatal编程技术网

Java 如何拥有一个只能由另一个特定类实例化的类

Java 如何拥有一个只能由另一个特定类实例化的类,java,android,kotlin,Java,Android,Kotlin,我想要一个只能由另一个类实例化的类。我知道我必须将构造函数设置为私有,否则每个人都可以实例化它 class Root private constructor() { } class RootMaker: Application() { fun createRoot() = Root() } // but this doesn't work because Root's constructor is private 一种解决方法是使maker类成为Root类的内部类 class Roo

我想要一个只能由另一个类实例化的类。我知道我必须将
构造函数
设置为私有,否则每个人都可以实例化它

class Root private constructor() {
}

class RootMaker: Application() {
    fun createRoot() = Root()
} // but this doesn't work because Root's constructor is private
一种解决方法是使
maker
类成为
Root
类的内部类

class Root private constructor() {

    class RootMaker: Application() {
        fun createRoot() = Root()
    } 
}

但我真的不想这样做,因为maker类是我在android中的
应用程序
类。那么更好的方法是什么呢?

如果您只需要一个对象实例,那么可以在Kotlin中使用关键字。它实现了
Singleton
模式:

class App : Application {
    
    val root = Root

}

object Root {
    fun createObject(): Any {}
}
现在我们可以通过
App
class中的属性或通过
Root
class:
Root.createObject()

更新:

要实现只有一个特定类可以访问的单例,我们可以使用接口并将其实现隐藏在该特定类中(maker类):


您可以将构造函数
设置为protected
RootMaker
设置为
Root
类的子类请求背后的原因是什么,因为我确实想知道这是否代表类型问题。除了检查调用线程的堆栈跟踪,并假设
Root
本身必须是公共的,我相信你能做的最好的事情就是将构造函数
设置为内部的
,并且确保永远不要在你的模块中的任何地方实例化这个类。尽管我认为,根据您的推理,您可以让
Root
负责保存singleton实例。Java和Kotlin都没有直接的机制来强制执行“只有这个类可以实例化另一个类”。在不使用黑客的情况下,您所能做的最好的事情就是战略性地使用可见性修改器。令人恼火的是,Kotlin不支持包私有可见性。您的选项包括:(1)记录使用要求并确保正确使用API,(2)检查堆栈跟踪以检查调用方,(3)使用反射来实例化,或(4)使用“friend accessor”模式(不确定此模式在Kotlin中是否有效)。我可能还缺少其他一些方法,下面是Java中“friend accessor”模式的一个例子:问题是我只希望一个类能够获取实例,我这里并没有要求使用singleton。它是一个只有一个特定类可以访问其实例的单例,我假定它是由
Any()
您的意思是
Root()
,我想作为实例的类。因此,此模式如何帮助防止其他类直接创建
Root()
。我知道的唯一方法是将其构造函数私有化,通过这样做,您建议的接口无法创建类tooNo,在您提到的注释中,“根类是我的CompositionRoot类,用于创建其他类的实例以进行依赖项注入”,因此,通过
Any
我指的是您想要创建的任何对象。让我把它取下来,以免把你弄糊涂。谢谢,这正是我所需要的。可以在接口上使用invoke()函数代替构造函数
interface IRoot {
    // ... methods of creation different objects for dependency injection
}

class App : Application {

    val root: IRoot = Root

    // hide implementation of `IRoot` interface in `App` class
    private object Root : IRoot {

        // ... implementation of methods of creation different objects for dependency injection
    }
}