我有一个类,它有一个生成随机数据的方法来填充数组。该类具有在private final Random rnd
的构造函数中初始化的数据成员new Random();
。这用于为数组生成数据的方法。
例如
package test;
import java.util.Random;
public class WorkWithArrays {
WorkWithArrays(Object[] arr) {
rand = new Random();
fillArrays(arr);
}
/*fills arrays with random data;
since this method is called from constructor
must be declared final*/
public final void fillArrays(Object[] arr) {
//code goes here
}
/*some other methods and data members*/
final private Random rand;
}
我正在编写一个新类,我还需要用随机值填充数组。有没有办法我不能重写相同的方法?我可以extend
这个类,或者我可以使方法静态。由于我只需要fillArrays()
使其成为static
似乎比extend
更好的选择。
所以让它静止。
public static final void fillArrays(Object[] arr) {
//code goes here
}
现在fillArrays()
使用rand
这是一个问题,因为rand
不是静态的。那么为什么不让它静止呢?现在在WorkWithArrays
中,我们不再在构造函数中初始化rand
,而是将其作为final static private Random rand = new Random();
作为数据成员。这是正确的吗?在构造函数之外初始化东西似乎是不好的做法。
现在我可以做到
包裹测试;
MyNewClass {
someMethod() {
int[] x = new int[25];
WorkWithArrays.fillArrays(x);
}
}
答案 0 :(得分:2)
这是不错的做法;正如沃伦所指出的,有一个static initializer构造用于此。
例如,要使用类似实用程序的方法创建类('函数' 并不真正需要状态),有几件事你可以做做。
这可以防止课程的扩展,这是没有意义的。
public final class WorkWithArrays {
// ...
}
这可以防止类被初始化
private WorkWithArrays() {}
你可以自己创建/初始化它(根本不是不好的做法!)
private static final Random rand = new Random();
或使用上述静态初始化程序
private static Random rand;
static {
rand = new Random();
}
请注意final
只能与静态属性一起使用,如果它是在线初始化。
一样简单
public static void fillArrays(Object[] arr) {
// code goes here
}
这是实现称为singleton类的设计模式的一种方式,实际上在整个OOP语言中非常常见。
在Java中,不是创建getInstance()
- 类型方法,而是通常在本地存储实例(或者根本不创建实例,例如这里的情况),静态方法引用内部存储的实例
初始化逻辑进入static { }
初始化程序块,在Java classloader首次加载类时执行。
请注意,在您的示例中(在撰写本文时),您在静态方法上拥有final
关键字。 This is not necessary,并且经常被静态分析器捕获为无效/无意义。
我通常不会为OP编写代码,但以下是构建类 1 的完美方法。
public final class WorkWithArrays {
private static final Random RAND; // = new Random();
static {
WorkWithArrays.RAND = new Random();
}
private WorkWithArrays() {}
public static void fillArrays(Object[] array) {
for (int i = 0, len = array.length; i < len; i++) {
array[i] = WorkWithArrays.RAND.nextInt();
}
}
}
1 导入已被省略
答案 1 :(得分:0)
静态变量通常在构造函数外部初始化。事实上,在Java中,有一个“静态初始化器”的概念,它专门用于初始化任何构造函数之外的静态变量,如果初始化对于简单的赋值来说太复杂了。
答案 2 :(得分:0)
静电越多,离物体方向越远。静态不受多态性的影响,并且很少使用状态来促进数据隐藏(因为所有实例在通过静态变量时都倾向于交叉通信)。
此外,阵列的许多(并非所有)细节也与面向对象的编程不一致,因为数组是数据的持有者而没有组合代码和数据的可能性。因此,数组缺乏行为,并将数据正确性的责任委托给其他不相关的代码片段。
对于面向对象的解决方案:
public class RandomIntList {
private int[] values;
public RandomIntList(int size) {
values = new int[size];
Random random = new Random();
for (int i = 0; i < size; i++) {
values[i] = random.nextInt();
}
}
}
请注意,现在您可以清楚地识别哪些对象是RandomIntLists,哪些不是,这对于int []来说是不可能的。
当然,如果你添加像
这样的东西public int[] asArray() {
return values;
}
你让猫从包里出来,因为其他代码可以修改类的内部状态而不通过类的边界(也就是接口或方法)。因此,为了使您的类面向对象,您有时需要复制(当数据可以变异时)。
public int[] asArray() {
return Arrays.copyOf(values, values.size);
}