Java 选择何时实例化类
我最近为一个作业编写了一个类,其中我必须将名称存储在ArrayList(java)中。我将ArrayList初始化为实例变量Java 选择何时实例化类,java,variables,performance,Java,Variables,Performance,我最近为一个作业编写了一个类,其中我必须将名称存储在ArrayList(java)中。我将ArrayList初始化为实例变量private ArrayList names。后来,当我对照解决方案检查我的工作时,我注意到他们在run()方法中初始化了ArrayList 我想了一会儿,我觉得这可能是一个品味的问题,但一般来说,在这种情况下,人们如何选择呢?一个人占用更少的内存还是什么 PS我喜欢Ruby中以@符号开头的实例变量:它们更可爱 (元问题:这个问题最好的标题是什么?用伟大的克努特的话说,“
private ArrayList names
。后来,当我对照解决方案检查我的工作时,我注意到他们在run()
方法中初始化了ArrayList
我想了一会儿,我觉得这可能是一个品味的问题,但一般来说,在这种情况下,人们如何选择呢?一个人占用更少的内存还是什么
PS我喜欢Ruby中以@符号开头的实例变量:它们更可爱
(元问题:这个问题最好的标题是什么?用伟大的克努特的话说,“过早优化是万恶之源” 只需担心你的程序功能正常,没有bug。这比以后难以调试的模糊优化要重要得多 但是为了回答您的问题-如果您在类成员中初始化,那么在代码中第一次提到您的类时(即,当您从中调用方法时),将分配内存。如果在方法中进行初始化,则稍后调用此特定方法时会进行内存分配
所以这只是以后初始化的问题。。。这在业界被称为延迟初始化 用伟大的克努斯的话说,“过早优化是万恶之源” 只需担心你的程序功能正常,没有bug。这比以后难以调试的模糊优化要重要得多 但是为了回答您的问题-如果您在类成员中初始化,那么在代码中第一次提到您的类时(即,当您从中调用方法时),将分配内存。如果在方法中进行初始化,则稍后调用此特定方法时会进行内存分配 所以这只是以后初始化的问题。。。这在业界被称为延迟初始化 来自: Java中变量的作用域有三种基本类型:
- 局部变量,在类中的方法内声明,在该方法执行时有效(且仅占用存储)。每次调用该方法时,都会使用变量的新副本
- 实例变量,在类内但在任何方法外声明。只要对应的对象在内存中,它就有效并占用存储空间;一个程序可以实例化类的多个对象,每个对象都有自己的所有实例变量副本。这是面向对象编程的基本数据结构规则;类被定义为保存特定于给定系统中“对象类”的数据,每个实例保存自己的数据
- 静态变量,在类内声明为静态,在任何方法外。无论从该类实例化了多少个对象,此类变量只有一个副本
- 局部变量,在类中的方法内声明,在该方法执行时有效(且仅占用存储)。每次调用该方法时,都会使用变量的新副本
- 实例变量,在类内但在任何方法外声明。只要对应的对象在内存中,它就有效并占用存储空间;一个程序可以实例化类的多个对象,每个对象都有自己的所有实例变量副本。这是面向对象编程的基本数据结构规则;类被定义为保存特定于给定系统中“对象类”的数据,每个实例保存自己的数据
- 静态变量,在类内声明为静态,在任何方法外。无论从该类实例化了多少个对象,此类变量只有一个副本
是的,内存消耗是一个问题,特别是如果run()中的ArrayList是本地的 我不完全理解你的全部问题 但就我目前的理解,性能/内存方面的好处将非常小。因此,我肯定会倾向于可行性方面
所以,做最适合你的事情。仅在需要时解决性能/内存优化问题 我不完全理解你的全部问题 但就我目前的理解,性能/内存方面的好处将非常小。因此,我肯定会倾向于可行性方面 所以,做最适合你的事情。仅在需要时解决性能/内存优化问题 初始化 根据经验,在声明变量时尝试初始化变量 如果一个变量的值永远不会改变,请使用
final
关键字明确表示。这有助于您分析代码的正确性,虽然我不知道编译器或JVM优化会识别final
关键字,但它们肯定是可能的
当然,这条规则也有例外。例如,可以在if–else或开关中分配变量。在这种情况下,“空白”声明(没有初始化的声明)比保证在读取伪值之前覆盖的初始化更可取
/* DON'T DO THIS! */
Color color = null;
switch(colorCode) {
case RED: color = new Color("crimson"); break;
case GREEN: color = new Color("lime"); break;
case BLUE: color = new Color("azure"); break;
}
color.fill(widget);
如果出现无法识别的颜色代码,则会出现NullPointerException
。最好不要分配无意义的null
。编译器将在调用color.fill()
时产生错误,因为它将检测到您可能尚未初始化color
为了回答你的问题,
class Oops extends Thread { /* Note that thread implements "Runnable" */
private int counter = 0;
private Collection<Integer> state = ...;
public void run() {
state.add(counter);
counter++;
}
public static void main(String... argv) throws Exception {
Oops oops = new Oops();
oops.start();
Thread t2 = new Thread(oops); /* Now pass the same Runnable to a new Thread. */
t2.start(); /* Execute the "run" method of the same instance again. */
...
}
}
// Lazy initialization holder class idiom for static fields
private static class FieldHolder {
static final FieldType field = computeFieldValue();
}
static FieldType getField() { return FieldHolder.field; }
// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) { // First check (no locking)
synchronized(this) {
result = field;
if (result == null) // Second check (with locking)
field = result = computeFieldValue();
}
}
return result;
}