Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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_Performance_Initialization - Fatal编程技术网

如何在Java中使用字段或局部变量初始化对象?

如何在Java中使用字段或局部变量初始化对象?,java,performance,initialization,Java,Performance,Initialization,以下情况下的性能/可靠性情况如何: public class A { private SomeObject a = new SomeObject(); //... public void method() { a.callSomeMethod(); } //... } 与: public class A { //... public void method() { SomeObject a = ne

以下情况下的性能/可靠性情况如何:

public class A {
    private SomeObject a = new SomeObject();

    //...

    public void method() {
        a.callSomeMethod();
    }

    //...
}
与:

public class A {
    //...

    public void method() {
        SomeObject a = new SomeObject();
        a.callSomeMethod();
    }

    //...
}
我明白了,从可测试性的角度来看,第二个选择不是那么好。 但是性能和可靠性呢?你应该走哪条路?将对象初始化为文件并大量使用它,还是每次需要时都初始化它

后期编辑:对象的构造不会花费很长时间。这种方法被大量使用

以下情况下的性能/可靠性情况如何

它们完全不同,在第一种情况下,
a
是类成员,在第二种情况下,
a
仅在
方法
的范围内已知。我不确定“比较”这两个代码的性能有多好


但是值得注意的是,第一个代码
someObject
中的。我不知道您调用了多少次
方法
,您的问题在当前版本中很难回答。

性能问题不是这里最大的问题

仅就性能而言,这取决于您的使用

第一个版本可能更好,因为您不必为每个方法调用创建新的
SomeObject

如果您创建了大量
a
s,并且只调用
method
几次,那么第二种方法会更好。(如@Marko Topolnik建议的)

然而,这里最大的问题是正确性。在
方法
的每次调用中使用相同的对象与在每次调用中使用新的
SomeObject
不同


这个问题比性能更重要。

主要区别在于变量的范围。首先是一个实例变量,然后是一个局部变量


如果对象只在该方法中使用,并且每次调用时都会更改,那么您可以使用第二种方法。实际上,如果您的
SomeObject
构造函数体包含执行可能需要很长时间的代码,那么在第二种情况下可能会出现一些真正的性能问题,因为在第二种情况下,每次调用
A.method()
时,您都在构造
SomeObject
对象。

这取决于具体情况。 演出 如果您想要评估两个抽象选项之间的性能差异,就像您在这里看到的那样;最好的办法是夸大一切的规模。例如,假设
SomeObject
实例化花费了过多的时间(比如600秒),并且您计划大量调用
method()
(因为在项目扩展之前,性能问题通常不会实现)

很明显,选项1在多次调用
method()
时会“执行”得更好,因为每次调用方法时,选项2都会导致一个巨大的操作。(是的,作为一个粗略的性能测试,您可以通过for循环运行每个选项并比较经过的时间,但应该很容易看出:在所有其他条件相同的情况下,创建一个对象n次要比创建一次对象花费更多的时间)

但在夸张的例子中,性能本身并不一定是在所有情况下支持选项1的理由。

建筑学 选择2 它实际上可以归结为
SomeObject
的体系结构。什么是某个对象?可能是
SomeObject
是一个在
A
的生命周期内无法打开的对象;例如,它可能是某种流读取器,在资源从流中读取时锁定资源。在这种情况下,您可能不想让
SomeObject
一直“打开”该资源;它应该在
method()
调用的末尾处理

选择1 好吧,但也许
SomeObject
类似于公开业务逻辑的服务或外观。正如您在问题中提到的,它“更适合于测试”,完整的答案是,是的,它为依赖注入提供了一个更容易的钩子,这是单元测试的关键组件。(虽然,通常它会被重写为
private SomeObject a;
,使用类似于
public a(SomeObject a){this.a=a;}
的构造函数,以遵循依赖注入/控制反转范例。但是,就本问题而言,最终结果是相同的。)

对于(设计良好的)服务或实用程序函数,您希望它能够自行(私下)处理对象处理。在这种情况下,使用率更高的模式是选项1,因为它为您提供了一个管理依赖关系的位置,而不是在使用它的每个方法中

你的选择 了解上述情况就足以做出明智的决定

  • 方案1-服务、立面、公用设施等
  • 方案2——需要处理的物体;实现
    Closable
    的对象,如
    StreamReader
    FileWriter

  • 是的。演出将会很受欢迎。在第一个场景中,并非每次输入method()时都会创建某个对象的对象。在第二种情况下,每次输入method(),都会创建一个新的SomeObject,这通常是不可取的。但另一方面,还必须查看对象和垃圾收集机制的范围。在第二种情况下,只要方法调用返回/结束,所创建对象的范围也将丢失。因此,它将可用于垃圾收集器。因此,如果内存是一个问题,那么您可能希望选择第二个选项。也就是说,如果有几百个对象被创建,那么你可能想考虑第二个选项。选项1的缺点是,只要类A的父对象实例存在,所有组合对象都将保持不变

    public class A {
        private SomeObject a1 = new SomeObject();
        private SomeObject a2 = new SomeObject();
    
        private SomeObject a1000 = new SomeObject();
        //...
    
        public void method() {
            a.callSomeMethod();
        }
    
    //...
    
    }

    上述代码的效率低于使用for循环和ca
    public class A{
       private SomeObject o;
    
       public void method(){
           if(o == null){
                o = new SomeObject();
           }
           o.callSomeMethod();
       }
    }
    
    public class A{
           private final SomeObject = new SomeObject();
           ....
    }