- 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/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!