[英]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.