概述
要点一
一般来说,最好能重用对象而不是在每次需要的时候创建一个相同功能的新对象。
反面例子
String a=new String("hello world");
该语句每次被执行的时候都会创建一个String实例,是完全没有必要的,如果此行代码在循环中则会创建成千上万的实例。
改进后
String a="hello world";
这行代码执行后只用了一个String的实例,而不是每次执行都会创建一个新的实例,并且下次调用时也不会创建,而是直接返回这个对象的引用,因为会保存在常量池中。但是如果是String a=new String("hello world")的话会则会创建两个对象,一个放在常量池中,另一个放在堆中,栈中存的是该对象的引用a。
要点二
使用静态工厂代替构造方法可以避免过多的创建对象。(在此不做解释请点击--->这里)
要点三
除了重用不可变对象外,还可以重用那些已知不会被修改的可变对象。
例如常见的原始jdbc开发流程
反面例子
public class DBUtil {
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
String URL="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8";
String USER="root";
String PASSWORD="123456";
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2.获得数据库链接
Connection conn=DriverManager.getConnection(URL, USER, PASSWORD);
//3.通过数据库的连接操作数据库,实现增删改查(使用Statement类)
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("select * from user");
//4.处理数据库的返回结果(使用ResultSet类)
while(rs.next()){
System.out.println(rs.getString("user_name")+" "
+rs.getString("user_password"));
}
//关闭资源
rs.close();
st.close();
conn.close();
}
}
getConnection()此方法会得到数据库连接对象,但是每次调用一次方法都会重新创建该实例。
改进后
public class DBUtil {
private static final String URL="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8";
private static final String USER="root";
private static final String PASSWORD="123456";
private static Connection conn=null;
static {
try {
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2.获得数据库的连接
conn=DriverManager.getConnection(URL, USER, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
//将获得的数据库与java的链接返回(返回的类型为Connection)
public static Connection getConnection(){
return conn;
}
}
使用static代码块来创建该实例,只有在类加载初始化的时候会实例化一次,大大减少内存的消耗。
要点四
有一种创建多余对象的新方法,称作自动装箱,它允许程序员将基本类型和装箱基本类型(引用类型)混用,按需要自动装箱和拆箱。自动装箱使得基本类型和引用类型之间的差别变得模糊起来,但是并没有完全消除。它们在语义上还有着微妙的差别,在性能上也有着比较明显的差别。考虑下面的程序,它计算所有int正值的总和。为此,程序必须使用long变量,因为int不够大,无法容纳所有int正值的总和。
例子
public static void main(String[] args) {
6
Long sum = 0L;
7
for(long i = 0; i < Integer.MAX_VALUE; i++){
8
sum += i;
9
}
10
System.out.println(sum);
11
}
这段程序算出的结果是正确的,但是比实际情况要慢的多,只因为打错了一个字符。变量sum被声明成Long而不是long,意味着程序构造了大约2的31次方个多余的Long实例(大约每次往Long sum中增加long时构造一个实例)。将sum的声明从Long改成long,速度快了不是一点半点。结论很明显:要优先使用基本类型而不是引用类型,要当心无意识的自动装箱。
总结
不要错误地认为"创建对象的代价非常昂贵,我们应该尽可能地避免创建对象"。相反,由于小对象的构造器只做很少量的显示工作,所以小对象的创建和回收动作是非常廉价的,特别是在现代的JVM实现上更是如此。通过创建附加的对象,提升程序的清晰性、简洁性和功能性,这通常是件好事。
最后
以上就是高高墨镜为你收集整理的避免创建不必要的对象的全部内容,希望文章能够帮你解决避免创建不必要的对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复