- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想在我的类中设置一个常量集,该常量对类的所有实例都是可见的。
首先,我不知道是否需要将其声明为“静态”。据我所知,静态字段的任何更改(由其中一个实例完成)都会被其他实例看到(因此静态变量未绑定(bind)到特定实例)。此外,可以在不使用任何实例的情况下更改静态字段(我们直接使用类)。因此,静态字段的所有这些特殊属性都与它的更改方式以及这些更改的效果有关。但就我而言,我希望有一个常数(因此“变化”问题在这里不相关)。所以,可能我不需要使用“静态”。对吧?
其次,我的集合将包含很多元素,我不想一次定义集合的值(当我创建变量时)。换句话说,我想声明一个集合,然后将元素逐步添加到这个集合中。但是如果我使用常量,我就做不到。是否可以指定集合的值,然后使其成为常量?
第三,我意识到如果我尝试在任何方法之外更改变量的值,可能会出现一些问题。那么,它是如何工作的呢?
已添加:
好的。多亏了答案,我明白它应该是“最终的”和“静态的”(因为它是一个常量集并且不会与任何特定实例关联,它应该对类的所有实例可见)。但是我仍然有问题。我想使用“添加”指定集合,如果它是常量(最终),我无法添加到集合中。此外,我不能在方法之外更改变量的值(为什么?)。无论如何,我不坚持使用“添加”来定义集合。我准备马上给它下定义。但我不知道该怎么做。我试过这样的事情:
final static Set allowedParameters = new HashSet("aaa","bbb");
final static Set allowedParameters = new HashSet(["aaa","bbb"]);
final static Set allowedParameters = new HashSet({"aaa","bbb"});
final static Set allowedParameters = new HashSet(Arrays.asList({"userName"}));
他们没有工作。
添加 2:
谁能解释一下 Tadeusz Kopec 给出的代码?
class YourClass {
private static void fillSet(Set<SomeType> set) {
// here you add elements, like
set.add(new SomeType());
}
private final static Set<SomeType> yourSetField;
static {
final Set<SomeType> tempSet = new HashSet<SomeType>();
fillSet(tempSet);
yourSetField = Collection.unmodifiableSet(tempSet);
}
}
1. fillSet
方法有一个名为“set”的变量。为什么不在方法中使用它?
2. fillSet
中的SomeType()
是什么?这个方法有什么作用?
3. fillSet
有什么作用?在示例的后面,我们为该方法提供了一个空集。做什么的?
4.为什么我们将 tempSet
声明为 final?
5. unmodifiableSet
究竟做了什么?我认为它根据名称生成一个无法修改的集合。但为什么将 yourSetField
声明为 final
是不够的?它也将是恒定的。
最佳答案
您是希望将元素添加到您的集合中一次,然后只读取其内容,还是希望能够随时向其中添加元素?如果您创建一次,请这样做:
class YourClass {
private static void fillSet(Set<SomeType> set) {
// here you add elements, like
set.add(new SomeType());
}
private final static Set<SomeType> yourSetField;
static {
final Set<SomeType> tempSet = new HashSet<SomeType>();
fillSet(tempSet);
yourSetField = Collections.unmodifiableSet(tempSet);
}
}
现在 - 它是私有(private)的,因此类(class)以外的任何人都无法访问它。而且它是不可修改的,因此没有人可以更改其内容。
如果你想随时添加元素,你会遇到并发问题 - 阅读 extraneon 的回答。
编辑
根据要求,我解释了这段代码的作用。
首先-神秘的<>括号:我假设您使用的是 Java 1.5 或更高版本并使用了 generics .简而言之 - 如果您声明一个 List 类型的变量,它包含对象。如果您希望在其中保留字符串,则必须在从列表中检索它们时强制转换它们。示例
List myList = new ArrayList();
myList.add("Hello, my Jon Skeet Number decreases");
String firstElement = (String) myList.get(0);
强制转换为 String 是必需的。此外,没有什么能阻止您将 BigDecimal 添加到 myList。但是,如果您检索它并尝试将其转换为 String,则会出现 ClassCastException。
myList.add(0, BigDecimal.ZERO); // perfectly legal
String anotherString = (String) myList.get(0); // compiles, but ClassCastException at runtime
因此 Java 1.5 引入了泛型。您可以指定 List 只能包含字符串。语法使用 <> 括号:
List<String> myList = new ArrayList<String>();
myList.add("Hi everybody");
String firstElem = myList.get(0); // no cast required
myList.add(BigDecimal.ZERO); // compiler error: cannot cast BigDecimal to String
这同样适用于其他集合,例如 Sets。我写了关于列表的文章,因为从列表中检索更方便。我用了SomeType
在我的例子中,因为我不知道你想在你的 Set 中保留什么。您应该将其替换为您希望存储的对象类型。
现在 - 静态 block 。有两种方法可以初始化静态字段 - 直接在它们的声明中:
static private int instanceCount = 0;
如果初始值是一个简单的表达式,这很有用。
或者在静态初始化 block
static {
// some code, that can use class static variables, class static methods, declare its own variables etc.
}
如果某些静态字段的初始值需要一些更复杂的计算,这很有用。
现在你的问题
set
的 fillSet
用来。添加了一个元素:set.add(new SomeType());
SomeType
.它将替换为您要使用的类型。 new SomeType();
创建(假设的)SomeType
的实例调用其无参数构造函数。fillSet
完全符合其名称的含义 - 获取一个集合并填充它(向其添加一些值)。我们给它一个空集,结果我们得到一个包含元素 fillSet
的集合。已放入其中。 fillSet
是你应该放置所有初始化你的集合的代码的地方。把它分开很好。tempSet
是静态初始化 block 中的局部变量,它被分配一次并且永远不会重新分配。为了表达这一点,我宣布它是最终的。这是我使用 findBugs 养成的习惯我认为这有利于提高可读性。yourSetField = new HashSet<SomeType>()
一旦初始化。但是任何可以访问 yourSetField
的人可以写yourSetField.add(...)
.如果yourSetField
是一个不可修改的集合,添加到它会导致运行时异常(UnsupportedOperationException
)。换句话说:final 意味着你不能制作 yourSetField
指向另一个对象(编译器保证)。 unmodifiableSet 意味着您不能在集合中添加或删除对象。它会编译,但会在运行时中断。关于java - 我应该如何为该类的每个实例声明一个可见的常量集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2417886/
我在覆盖 ReSwift Pod 中的函数时遇到问题。我有以下模拟类(class): import Foundation import Quick import Nimble import RxSwi
我有一个类似于下面的继承结构。我正在采用 Printable 协议(protocol)并努力覆盖 description 属性。我遇到了一个谷歌此时似乎不知道的奇怪错误,提示为第三类,并引用了第二类和
我有一个类“Cat”和 Cat 类的一个子类“DerivedCat”。 Cat 有一个函数 meow(),而 DerivedCat 覆盖了这个函数。 在应用程序中,我声明了一个 Cat 对象: Cat
Kotlin 变量 变量是用于存储数据值的容器。 要创建一个变量,使用 var 或 val,然后使用等号(=)给它赋值: 语法 var 变量名 = 值 val 变量名 = 值 示例 va
C 中的所有标识符在使用前都需要声明,但我找不到它在 C99 标准中表示的位置。 我觉得也是指宏定义,不过定义的只是宏展开顺序。 最佳答案 C99:TC3 6.5.1 §2,脚注 79 明确指出: T
今天我的博客提要显示错误: This page contains the following errors: error on line 2 at column 6: XML declaration
在编写 IIF 语句、表和下面给出的语句时出现错误。 陈述: SELECT IIF(EMP_ID=1,'True','False') from Employee; table : CREATE TAB
我正在创建一个登录 Activity ,我希望它在按下登录按钮时显示进度对话框,我声明、初始化并调用了它,但它没有显示。但是当我在创建时调用进度对话框时,它出现了 这是我的代码: public cla
当我输入声明语句时: Vector distance_vector = new Vector(); 我收到错误(在两种情况下都在“双”下划线): Syntax error on token "doub
我正在本地部署在docker-for-desktop中。这样我将来可以迁移到kubernetes集群。 但是我面临一个问题。使用永久卷时,docker容器/ pod中的目录将被覆盖。 我正在拉最新的S
我有一个 MyObject 类型的对象 obj,我声明了它的实例。 MyObject obj; 但是,我没有初始化它。 MyObject 的类看起来像: public class MyObject {
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
这个问题已经有答案了: Android: Issue during Arraylist declaration (1 个回答) 已关闭 9 年前。 有时我会看到 ArrayList 声明如下 Arra
我对java比较陌生,经过大量搜索,我无法将相关问题的任何解决方案与我的解决方案配对。我正在尝试实现一种非常简单的方法来写入/读取数组,但编译器无法识别它。 “键盘”也是一个“无法识别的变量”。这是数
简短:何时分配内存 - 在声明或初始化时? 长整型:int x;将占用与int z = 10;相同的内存。 此外,这对于包含更多数据的自定义对象将如何工作。假设我有这个对象: public class
我需要使用此程序更好地理解函数定义、声明和正确调用。我真的需要了解如何使用它们。您能否向我展示编写此程序的正确方法(所有三个都正确并进行解释)? #include #include quad_eq
这是我的主要功能以及我要传递的内容。 int main(void){ struct can elC[7]; // Create an array of stucts Initiali
我想知道是否有更好的方法来完成此任务; 我有一个对象 - 其中一个属性是字典。我有一组逗号分隔值。我需要过滤 Dictionary 并仅获取 Dictionary 值至少与其中一个值匹配的那些元素 这
下面的using-declarations有什么意义 using eoPop::size; using eoPop::operator[]; using eoPop::back; using eoPo
我的问题更像是一个关于 for 循环样式的好奇问题。在阅读别人的一些旧代码时,我遇到了一种我以前从未见过的风格。 var declaredEarlier = Array for(var i=0, le
我是一名优秀的程序员,十分优秀!