Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java优化:声明类变量与使用临时变量_Java_Optimization_Class Variables_Code Readability_Temporary Objects - Fatal编程技术网

Java优化:声明类变量与使用临时变量

Java优化:声明类变量与使用临时变量,java,optimization,class-variables,code-readability,temporary-objects,Java,Optimization,Class Variables,Code Readability,Temporary Objects,首先,如果我的英语不完美,请原谅,但我不是来自英语国家(西班牙),所以 好吧,问题来了。创建类时,最好尽可能使用临时变量,或者最好将变量声明为类变量,只是为了保持清楚 我将给出一个示例,使用一个简单的类SpriteSheet。是一个非常短且流行的类,几乎在Java中的所有2D游戏中都使用 以下是我正在观看的教程的创建者最初计划的代码: public class SpriteSheet { private String path; private final int SIZE; public i

首先,如果我的英语不完美,请原谅,但我不是来自英语国家(西班牙),所以

好吧,问题来了。创建类时,最好尽可能使用临时变量,或者最好将变量声明为类变量,只是为了保持清楚

我将给出一个示例,使用一个简单的类SpriteSheet。是一个非常短且流行的类,几乎在Java中的所有2D游戏中都使用

以下是我正在观看的教程的创建者最初计划的代码:

public class SpriteSheet {

private String path;
private final int SIZE;
public int[] spriteSheetPixels;

public SpriteSheet(String path, int size) {
this.path = path;
SIZE = size;

spriteSheetPixels = new int[SIZE * SIZE];

load();
}

private final void load() {
try {
    BufferedImage image = ImageIO.read(SpriteSheet.class
        .getResource(path));
    int w = image.getWidth();
    int h = image.getHeight();
    image.getRGB(0, 0, w, h, spriteSheetPixels, 0, w);
} catch (IOException e) {
    e.printStackTrace();
}
}
}

关键是,他只是在做一个普通的类,按照我所知的所有Java约定。看了之后,我想我可以改进一下。这是我对同一类的看法:

public final class SpriteSheet {

public final int[] spriteSheetPixels;

public SpriteSheet(final String path, final int width, final int height) {
spriteSheetPixels = new int[width * height];

load(path, width, height);
}

private final void load(final String path, final int width, final int height) {
try {
    BufferedImage image = ImageIO.read(SpriteSheet.class
        .getResource(path));

    final int w = image.getWidth();
    final int h = image.getHeight();
    final byte ZERO = 0;

    image.getRGB(ZERO, ZERO, w, h, spriteSheetPixels, ZERO, w);
} catch (IOException e) {
    e.printStackTrace();
}
}
}

以防万一,如果您不想太在意,我将尝试恢复我所做的更改以及原因: -在类声明中添加了“final”,因为我认为我永远不需要实例化它。 -删除了除数组之外的所有类变量,因为它是我将从此类中使用的唯一对象。我觉得将其余变量声明为类变量只是浪费内存。如果它们是临时的,如果我没有弄错的话,它们将被使用,然后GC迟早会处理它们,释放内存。 -将数组标记为final,因为它将在运行时的其余时间保持原样。 -将大小常量拆分为宽度和高度,以防我决定使用一些非方形的精灵表。 -声明w和h实际上是一个很好的想法,因为在参数中调用方法通常不利于执行速度(或者我在某些地方读到了这一点)。 -由于0被多次使用,我相信将其声明为变量将有助于提高执行速度(只是一点点,可能无论如何都不会引起注意)

基本上就这些。请注意,我是一名学生,可能犯了一些非常n00b的错误,这就是我想在这里提问的原因,因为我相信周围有很多经验丰富的程序员

简单地说,我并不真正关心SpriteSheet类,我更好奇我的优化质量

?我是改进了还是让事情变得更糟(让事情变得更慢、可读性更低、将来更难维护、做编译器无论如何都会做的事情

对不起,如果我的问题太长太模糊,那么我的第一个问题对我来说很简单;)

提前谢谢

编辑:

我只是在稍作休息后读了一下,这没有任何意义(您是否看到我正在解析宽度和高度参数以加载(),但从未使用它们?)

我认为应该是这样的:

public final class SpriteSheet {

public final int[] spriteSheetPixels;

public SpriteSheet(final String path, final int width, final int height) {
final byte ZERO = 0;
spriteSheetPixels = new int[width * height];

try {
    BufferedImage image = ImageIO.read(SpriteSheet.class
        .getResource(path));

    image.getRGB(ZERO, ZERO, width, height, spriteSheetPixels, ZERO,
        width);
} catch (IOException e) {
    e.printStackTrace();
}
}
}

我才意识到我真的不需要这种方法。一切都可以在构造函数中完成

或者最好将变量声明为类变量,只是为了保持清楚

我想你指的是“属性”(实例变量),而不是静态(类)变量。将所有内容声明为实例变量会使事情变得非常不清楚

简短回答:对于跨不同方法共享的数据,仅在严格必要时使用局部变量并创建属性。此外,局部变量的访问速度可能比属性稍快

创建类时,最好尽可能使用临时变量,或者最好将变量声明为类变量,只是为了保持清楚

如果信息仅与当前运行的方法相关,则将其存储在一个范围尽可能小的局部变量中

如果有关对象的信息需要在任何一个方法调用之后持续,并且无法从其他源派生,则将其存储在字段中

如果可以从其他来源获取有关对象的信息,但继续获取该信息效率低或不方便,则记录其与其他数据的关系,可能会标记该信息并将其存储在字段中

如果你发现一个类有很多字段,那么也许是时候把它分解成更小的类了。
同样,如果一个方法包含许多局部变量,那么也许是时候尝试将其分解为更小的方法了。

假设您的示例中所指的是实例变量,而不是类/
静态
变量。(如果你真的是指
静态
变量,那么你还有很多其他问题要处理…)


让我们从这个问题的“优化”方面开始

首先要说的是,这两种方法之间的差异可能微不足道。很可能它不会对程序的性能产生明显的影响。在您的情况下,我可以想象您在任何时候最多有几十个该类的实例,因此内存使用的差异最多只有几千字节

话虽如此,还是有区别的。当您将字段声明为实例字段时,它们将在对象的生存期内存在(并占用堆内存)。相反,当封闭方法调用结束时,局部变量就不存在了。因此,从长远来看,使用局部变量可能会占用更少的内存


但这里的重要问题是可读性、可维护性和正确性

如果您将局部“临时”变量转换为实例变量,那么就有不同方法的作用域。。。或对同一方法的不同调用。。。通过使用实例变量相互干扰。请注意,在某些用例中,干扰是不可避免的。例如,当两个不同的线程同时调用同一对象上的同一方法时,或者当一个方法直接或间接地调用自身时;i、 递归

事实上,这样的事情可能会发生,这使得代码更难阅读和维护。(除非你是真的