繁体   English   中英

Java中的变量重用

[英]Variable reuse in java

在使用Java处理SQL事务的类中,我经常使用类PreparedStatement和ResultSet。

我很好奇知道什么是Java更好(更有效)的实践。 宣布他们为班级成员...

class SqlThingy {
    PreparedStatement pstx;
    ResultSet rs;
    public void SqlThingyMethod() {
         pstx = database.connection.prepareStatement("...");
         ....
    }
}

...还是作为单个方法的局部变量?

class SqlThingy {
    public void SqlThingyMethod() {
        PreparedStatement pstx;
        ResultSet rs;
        pstx = database.connection.prepareStatement("...");
    }
}

VM是仅使用新的preparedstatement(引用)覆盖类成员的内容,还是会做一些额外的初始化,这些初始化也要求资源,甚至抵消每次分配局部变量的差异?

确保区分变量及其指向的对象。 作为一般原则,请勿重用变量以指向不同的对象。 这极容易出错。

在您的特定示例中,由于您在每次调用SqlThingyMethod都在重新创建连接对象,因此将其存储在字段中可能没有任何好处。 使用局部变量。

变量很便宜。 即使不是很昂贵,物品也会便宜些。 在这种情况下,对象实际上可能是昂贵的,但变量不是。

实例级字段不是线程安全的,因此JVM必须确保正确访问/使用它们(尽管转义分析在很大程度上很好地对此进行了优化)。

方法局部变量是线程安全的,因此JVM不必过多担心实例的使用方式。

因此,最好使用方法2(除非您从其他地方获取引用,并且引用不包含在方法内)。

您的实例变量pstx只是一个保存引用的插槽。 您并没有真正重用同一对象,只是坚持了一个过时的引用,直到出现另一个方法调用并将其覆盖。

PreparedStatement和ResultSet是从数据库连接创建的,如果获得新的数据库连接,则也必须获得新的PreparedStatement。 您不能在连接之间重用PreparedStatement或ResultSet。

对PreparedStatement和ResultSet使用局部变量,并在完成使用后将其关闭:获取连接,执行操作,并在方法退出时关闭所有jdbc资源。 让这些对象的停留时间比绝对必要的时间长,对您没有任何好处,并且可以防止数据库服务器资源尽快释放。

唯一可用的优化是,如果您使用相同的连接进行重复操作,则为所有连接保留相同的PreparedStatement实例是有意义的,以便数据库服务器可以准备和重用该sql。

您没有说要在其中编写此代码的上下文。对于Web应用程序,您需要连接池,请参阅是否有永远不关闭JDBC连接的原因? 如果您要对Web应用程序中的所有查询重新使用相同的连接。

简短的答案是:这取决于。

长答案是:

  • 如果要在整个程序中使用该变量,则最好将它们声明为类的成员。
  • 如果仅在一种方法或块中使用变量,则在块中声明它会更好。

您似乎认为您正在重用某些东西,但实际上并没有。 每次调用该方法时,两个示例中都会创建一个新对象。

两个主要区别:

  • 在第二个示例中,对象在方法退出后就可以进行垃圾回收了-在第一个示例中,直到再次调用该方法或包含对象才可以进行垃圾回收,它们才可以被垃圾回收
  • 在第二个示例中,使用时,任何外部代码都无法修改您的语句-在第一个示例中,其他引用您的类的代码可能会修改准备好的语句并弄乱您的工作

底线:始终尝试将范围保持在最小范围内(即,尽可能使用局部变量)。

将变量的范围限制在使用变量的最小范围是一种很好的做法。 在这种情况下,尽管您将重用变量,但要考虑到变量将引用对象,例如,ResultSet将引用查询的结果。 如果让变量超出范围(将其声明为局部变量),则将准备好由GC收集引用的值(及其填充的内存)。 如果您将其用作类变量,则时间将过去,并且您的内存将保持被该变量引用,因此在您的“ SqlThingy”类实例超出范围之前,它不会空闲。

答案是“取决于”,但总的来说,第二点在性能和安全性上都更好。

第一个可能导致pstx生存时间比第二个更长,并且还将禁用JVM优化,例如转义分析,堆栈分配等。

首选第一个实例的唯一原因几乎是可以重复使用实例,从而避免了初始化成本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM