Java 在包外隐藏构造函数
我试图将类构造函数隐藏在包范围之外(以及其他一些setter),并强制潜在的包用户仅通过其生成器获取这个特定的类(为了清晰和验证) 到目前为止,我一直在通过将该类及其构建器放在同一个包中,并为我想要隐藏的所有方法声明包可见性来实现这个目标。然而,这也有一些缺点。它强加了更严格的包结构,并限制了用户扩展类生成器的可能性Java 在包外隐藏构造函数,java,oop,Java,Oop,我试图将类构造函数隐藏在包范围之外(以及其他一些setter),并强制潜在的包用户仅通过其生成器获取这个特定的类(为了清晰和验证) 到目前为止,我一直在通过将该类及其构建器放在同一个包中,并为我想要隐藏的所有方法声明包可见性来实现这个目标。然而,这也有一些缺点。它强加了更严格的包结构,并限制了用户扩展类生成器的可能性 我很好奇是否有其他解决方案或模式?我之前听说过关于在Java中引入“模块”可见性修饰符的谣言(我认为这可以解决问题),但我想他们已经放弃了这个想法 -使用受保护的访问修饰符限制该包
我很好奇是否有其他解决方案或模式?我之前听说过关于在Java中引入“模块”可见性修饰符的谣言(我认为这可以解决问题),但我想他们已经放弃了这个想法 -使用
受保护的
访问修饰符限制该包之外的构造函数代码的访问
例如:
public class FilePro {
protected FilePro(){ // This block is accessible only
// within this package
}
}
-使用
受保护的
访问修饰符限制该包之外的构造函数代码的访问
例如:
public class FilePro {
protected FilePro(){ // This block is accessible only
// within this package
}
}
使用公共生成器静态内部类:
public class OuterClass{
private MyType1 field1;
private MyType2 field2;
private OuterClass(MyType1 field1, MyType2 field2){....}
public static class Builder{
private static final MyType1 DEFAULT_VALUE_1 = something;
private static final MyType2 DEFAULT_VALUE_2 = somethingelse;
private MyType1 field1=DEFAULT_VALUE_1;
private MyType2 field2=DEFAULT_VALUE_2;
public Builder() {...}
public setFiled1(MyType1 field1) { this.field1 = field1)
public setFiled2(MyType2 field2) { this.field2 = field2)
public OuterClass build() { return new OuterClass(field1,field2);}
}
}
为了进一步增强健壮性,请使outerClass final中的字段使用公共生成器静态内部类:
public class OuterClass{
private MyType1 field1;
private MyType2 field2;
private OuterClass(MyType1 field1, MyType2 field2){....}
public static class Builder{
private static final MyType1 DEFAULT_VALUE_1 = something;
private static final MyType2 DEFAULT_VALUE_2 = somethingelse;
private MyType1 field1=DEFAULT_VALUE_1;
private MyType2 field2=DEFAULT_VALUE_2;
public Builder() {...}
public setFiled1(MyType1 field1) { this.field1 = field1)
public setFiled2(MyType2 field2) { this.field2 = field2)
public OuterClass build() { return new OuterClass(field1,field2);}
}
}
为了进一步增强健壮性,将outerClass中的字段设为final我对Java没有太多的研究,但我相信您可以做的是声明一个创建类实例的静态方法
public static build()
{
return new FilePro();
}
这样,您就可以只从同一个包中创建一个新的类实例,并且可以不受任何限制地扩展该类我对Java的使用不多,但我相信您可以声明一个创建该类实例的静态方法
public static build()
{
return new FilePro();
}
通过这种方式,您可以仅从同一个包创建该类的新实例,并且可以不受任何限制地扩展该类。首先,我建议在产品中进行完全验证(以及复制可变值),而不是信任客户机 如果要将客户端正在使用的构建器界面与产品分离,请添加该间接层 最简单的方法是让产品公开一个具有大量参数列表的构造函数,并执行通常的构造函数职责(复制可变参数、验证参数并确保将对象初始化为可用状态)。构建器可以位于不同的依赖包/模块/jar/库中,并使用构造函数接口 所以现在我们回到大构造器。您可以通过多种方式解决此问题。例如,您可以在同一个类/包/模块中有一个规范构建器,其他对象可以使用它
或者,您可以使用一个带有“get”方法的接口(去掉
get
前缀,在一种get类型中它是毫无意义的)替换构造函数中的每个参数。产品构造函数现在只需要一个参数,并且可以提取每个参数。当完成产品构建时,每个构建者都可以将接口实现为匿名内部类(例如)。首先,我建议在产品中进行完整验证(以及复制可变值),而不是信任客户
如果要将客户端正在使用的构建器界面与产品分离,请添加该间接层
最简单的方法是让产品公开一个具有大量参数列表的构造函数,并执行通常的构造函数职责(复制可变参数、验证参数并确保将对象初始化为可用状态)。构建器可以位于不同的依赖包/模块/jar/库中,并使用构造函数接口
所以现在我们回到大构造器。您可以通过多种方式解决此问题。例如,您可以在同一个类/包/模块中有一个规范构建器,其他对象可以使用它
或者,您可以使用一个带有“get”方法的接口(去掉
get
前缀,在一种get类型中它是毫无意义的)替换构造函数中的每个参数。产品构造函数现在只需要一个参数,并且可以提取每个参数。当完成产品构建时,每个构建者都可以将接口实现为匿名内部类(例如)。请再次阅读我的问题。这正是我已经提到的解决方案;-)请再读一遍我的问题。这正是我已经提到的解决方案;-)这很好,但它会关闭任何扩展的构建器。如果您想授权继承,请使OuterClass
constructorprotected
允许继承构建器来构建OuterClass实例,这难道不奇怪吗?也许您是对的,但这就是我面临的问题。用户需要能够自定义对象初始化,但我想在最终创建的类实例中隐藏所有不必要的方法。然后,您应该只在生成器中公开public setters方法。对于未明确设置的字段,可以使用默认值。在这种情况下,不应使用继承。在外部类中,不实现setter,只实现getters这很好,但它会关闭任何扩展的构建器。如果要授权继承,请使OuterClass
constructorprotected
允许继承构建器来构建OuterClass实例,这难道不奇怪吗?也许你是对的,但这就是我面临的问题。用户需要能够自定义对象初始化,但我想在最终创建的类实例中隐藏所有不必要的方法。然后,您应该只在生成器中公开public setters方法。对于未明确设置的字段,可以使用默认值。在这种情况下,不应使用继承。在外部类中,不实现setter,只实现gettermethodobuild()
必须是公共的,才能在包methodo之外创建实例<