gpt4 book ai didi

java - 我应该如何为该类的每个实例声明一个可见的常量集?

转载 作者:搜寻专家 更新时间:2023-11-01 04:03:47 27 4
gpt4 key购买 nike

我想在我的类中设置一个常量集,该常量对类的所有实例都是可见的。

首先,我不知道是否需要将其声明为“静态”。据我所知,静态字段的任何更改(由其中一个实例完成)都会被其他实例看到(因此静态变量未绑定(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 是必需的。此外,没有什么能阻止您将 Bi​​gDecimal 添加到 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.
}

如果某些静态字段的初始值需要一些更复杂的计算,这很有用。

现在你的问题

  1. 参数setfillSet用来。添加了一个元素:set.add(new SomeType());
  2. 因为我不知道你想在你的集合中保留什么,所以我将其元素的类型命名为 SomeType .它将替换为您要使用的类型。 new SomeType();创建(假设的)SomeType 的实例调用其无参数构造函数。
  3. fillSet完全符合其名称的含义 - 获取一个集合并填充它(向其添加一些值)。我们给它一个空集,结果我们得到一个包含元素 fillSet 的集合。已放入其中。 fillSet是你应该放置所有初始化你的集合的代码的地方。把它分开很好。
  4. tempSet是静态初始化 block 中的局部变量,它被分配一次并且永远不会重新分配。为了表达这一点,我宣布它是最终的。这是我使用 findBugs 养成的习惯我认为这有利于提高可读性。
  5. 使 yourSetField 最终化意味着您不能写 yourSetField = new HashSet<SomeType>()一旦初始化。但是任何可以访问 yourSetField 的人可以写yourSetField.add(...) .如果yourSetField是一个不可修改的集合,添加到它会导致运行时异常(UnsupportedOperationException)。换句话说:final 意味着你不能制作 yourSetField指向另一个对象(编译器保证)。 unmodifiableSet 意味着您不能在集合中添加或删除对象。它会编译,但会在运行时中断。

关于java - 我应该如何为该类的每个实例声明一个可见的常量集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2417886/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com