如何在Java字段中设置基数?
让我们假设我们有以下类:如何在Java字段中设置基数?,java,Java,让我们假设我们有以下类: public class MyClass{ List<String> list; void method() { } } 公共类MyClass{ 名单; void方法(){ } } 这个类的每个对象都有一个字符串列表,但是如果我们想设置基数呢?例如,我想强制该类在该列表中至少有两个字符串 是否有一种通用模式来表示字段的基数?一种方法是为字段使用不同的类型。现在它有了类型List,这是一个可以包含0个或更多元素的集合。您可以将其更
public class MyClass{
List<String> list;
void method() {
}
}
公共类MyClass{
名单;
void方法(){
}
}
这个类的每个对象都有一个字符串列表,但是如果我们想设置基数呢?例如,我想强制该类在该列表中至少有两个字符串
是否有一种通用模式来表示字段的基数?一种方法是为字段使用不同的类型。现在它有了类型
List
,这是一个可以包含0个或更多元素的集合。您可以将其更改为表示包含2个或更多元素的列表的类型 您只需通过某种方式确保列表中至少有2个元素。没有标准或简单的方法可以做到这一点
这被称为类的不变量。作为编写类的人,您有责任确保始终保留该不变量。特别是:
- 您需要记录列表中至少有2个元素的不变量
- 您需要确保在构造函数完成时,
列表
至少包含两个元素。当构造函数完成时,实例应该是“有效的”(在其文档化的不变量为true的意义上)
- 您需要确保类中的所有代码在处理列表时都遵循不变量-您可以临时使其无效,但必须确保不可能观察到处于无效状态的实例
在单线程情况下,这仅仅意味着一旦公共方法返回,不变量必须为true(注意,这包括是否发生异常);但是,如果您的代码设计为以多线程方式使用,您还必须确保任何线程都无法在不变量为false的状态下看到您的实例(例如,您可能需要
同步的块,或者确保更新是原子的)
- 您需要确保类的子类不能使不变量为false;或者清楚地记录,编写子类的人有责任确保不变量保持为真
在有效的Java2ndEd中有一个很好的条目:“设计并记录继承,否则禁止继承”
- 您需要确保类外的任何内容都无法访问对列表的引用。例如,您的代码使列表对同一包中的其他类可见-这些类中的任何一个都可以调用instance.list.clear()
,并使您的不变量无效
这是很难绝对防止的——例如,恶意参与者可能会使用反射使不变量无效。您可以避免这种情况,但这是一个权衡识别和阻止此类方法的努力与不变量变为false的实际成本的问题(这在很大程度上取决于如何使用此类)
到目前为止,实施不变量的最简单方法是在不可变类上。如果不可能更改实例的可观察状态,则不可能使不变量无效。然后,您需要担心的是a)确保类是不可变的;b) 确保构造函数返回后,不变量为true。上面的所有其他点都会消失。您可以在构造函数中使用var args
public MyClass(String s1, String s2, String... rest){
}
是否存在表示字段基数的通用模式
显然,您可以在对象本身或元级别使用整数字段表示基数。但如果你不能强制执行,那就没什么帮助了
这方面没有一般模式@安迪·特纳(Andy Turner)的回答很好地总结了执行基数的备选方案。我只想补充两点:
- 使构造函数私有化
- 在建筑时,使用其他私人方式避开基数
- 检查基数并在
方法中翻转开关(需要)build()
1-理论上,您可以实现一个
listoftwormore
接口,等等,但这会带来大量新问题。然后您只需要确保列表中至少有2个元素。除了在构造函数返回后确保不变量为真之外,没有标准的方法可以做到这一点。有几种使用AOP的方法,尽管我不知道如何使用AOP