关于Java函数调用的一点体会

首先请大家看看下面两段代码有什么区别:

代码1:

List<Task> tasks = new ArrayList<Task>();

Task[] allTask = DemoData.getTasksData();
 for(int i=0;i<allTask.length;i++){
        tasks.add(allTask[i]);
 }

 

--------------------------------------------------

代码2:

List<Task> tasks = new ArrayList<Task>();

for(int i=0;i<DemoData.getTasksData().length;i++){
        tasks.add(DemoData.getTasksData()[i]);
 }

-------------------------------------------------

 

从上面的代码可以看出,两种处理方法的不同主要体现在:一个是使用临时变量存储函数返回的结果,而另一个是直接使用函数调用的返回值

那么它们之间有什么区别呢?

 

原来,对于第一种方法,函数只调用了一次,而第二种方法调用了多次,采用第二种方法的人貌似是想节省一些“不必要的”变量以节省空间并使代码更简洁,其实适得其反,因为每次函数调用都会返回一个“临时变量”,而且如果DemoData.getTasksData()有大量的内存操作,那么这种开销是相当巨大的。

 

如果对内存要求不高,一般不会发现问题,但是如果DemoData.getTasksData()中有对内存进行的操作,特别是建立对象的操作,而对象间又存在一些依赖或关联关系,则第二种方法由于每循环一次都会调用DemoData.getTasksData()一次,因此对象间建立的关系并没有建立起来,tasks每次add的都是另一个版本的tasks data中的一个task,那次以后在使用tasks的时候就会出现问题:要么一个task的前置任务task找不到,要么为null,找不到是因为关联关系并没有建立正确,为null是因为多次申请的“无用对象”已经被释放了。

 

所以从这段示例中可以总结一点,对于一个存在返回值的函数,最好使用一个变量保存该返回值,以后直接使用该变量即可 (当然,涉及到深拷贝、浅拷贝之类的问题再另谈)。特别是对于Java,由于Java默认使用地址比较两个对象是否相等,所以采用第二种方法往往出现令人诧异的结果:因为不管你怎么System.out.println输出总是对的,然而他们只是内容一样,实际并不是相同的对象。

 

你可能感兴趣的:(关于Java函数调用的一点体会)