要看那种情况,假如你的这个变量是作为循环体内使用,那么用“全局”吧,如:
Student student=null;
for(Iterator iter=datas.iterator();iter.hasNext();){
student=(Student)iter.next();
}
这样可以节约时间,不用没一次循环都要在栈中申请空间以存储引用;
假如是在类一级的,比如作为类的属性还是方法的变量,原则是假如方法的参数不是很多的话,那么采用方法传递,楼主也说了,可以采用多线程或是池。
Student student=null;
for(Iterator iter=datas.iterator();iter.hasNext();){
student=(Student)iter.next();
}
这样可以节约时间,不用没一次循环都要在栈中申请空间以存储引用;
假如是在类一级的,比如作为类的属性还是方法的变量,原则是假如方法的参数不是很多的话,那么采用方法传递,楼主也说了,可以采用多线程或是池。
2.最少通信原则我也同意这点,但是这和“类内部强耦合”相冲突,希望多讨论讨论这方面~~~~~~再一个,对于“2.我们写的类到时候要被多线程调用的,所以局部变量更好一点”这一点,我的想法是:
“变量是全局的还是局部的,和多线程调用并无关系,到时只要在总方法上加上synchronized就
好,而且,即使变量是局部的,要是多线程调用时,也得加上同步不是?”也请在这一点上多发言~~~~~~~~
再次谢谢大家的发言~
如果对一个变量的使用率频繁建议使用全局。可以节省CUP分配内存空间的时间。
如果使用局部变量。虽然在整个程序运行期内存资源消耗减少。可是CUP要花更多时间用在内存资源分配上。
(如果是public,又会怎么样呢?作深层次讨论更好:))
private HashMap hm;//呵呵,我称此种为全局变量
public Test(){ }
...
...
}至于这种变量是否要为public或protected,我想取决于它和外部类的依存关系。咱们还是把注意力放在类内部的这种变量的声明方法吧~~~~~
private String s;
protected HashMap hm;
private List list;
public ... ...
public Test(){
s = "test";
hm = new HashMap();
list = new ArrayList();
... ...
}
}可以这么说,凡是在构造方法中创建的变量都是这种意义上的局部变量,那就是说,如果其为非private的话,那么是提供给别的类访问用的,是可以声明为这种意义上的全局变量的,那么如果是private的话,那么本就不应该这么去创建和声明???而应该尽可能得把它放在局部去声明和创建,应用的时候,靠方法的参数和返回值来通信????
还有一点,面向对象的思想强调的是“对象和对象的有机联系”,那么,一个类中如果就只有方法,那么跟以前面向过程编程一样了吗?这样做是不是违背了面向对象的初衷呢?
>>
错了,其实不完全是这样的。因为很有可能这个类本身的存在,就是面向对象的一个部分。比如,俺给你举一个简单的例子来说明吧:
一个配置加载的类比如说ConfigLoader从配置文件中加载配置信息,配置可能是这样的nv对:
name : value.
作为客户来说,并不需要关心这个value是什么,可能只是需要根据这个value创建出来的一些结果,比如配置类名通过反射机制来创建就可以了。
那么通常ConfigLoader这么做:假设使用HashMap来存储:
final Map map = new HashMap();
// ... 读取配置文件的内存
for(each:...) {
String name = each.getName();
String value = each.getValue();
Object actualValue = build(value);
map.put(name, actualValue);
}
Object build(String value) {...}
// ..
这样是一种通常的做法,但是如果细了说,ConfigLoader这个类实际上有两个职责了:
(1) 加载配置文件。
(2) 根据指定的value来构建对象实例。
可能会导致的问题是,第一构建方法的变化会导致ConfigLoader这个不相关的类的修改,第二,对单元测试增大了难度,至少看起来不是一个优美可测的结构。因此,在这样的情况下,就可以把构建的内容单独抽离到一个新的对象中去做:
class Builder {
Object build(String value) {...}
}
刚才的程序片断就简单变为:
map.put(each.getName(), new Builder().build(each.getValue());
这样,即便构建的逻辑发生变化,对于ConfigLoader来说是没有任何影响的。楼主可以看看比如Builder这个类,它本身没有任何变量,就是提供了一个build的方法。。但是它本身就是体现了面向对象的一个部分,它承担了构建这个责任。=================
另外,也有变成面向过程的编程,通常就是俺们经常使用的工具类,就是做的面向过程的事情。
final public class Utils {
private Utils() {}
public static void someMethod(...) {...}
}
这个someMethod就是一个典型的面向过程的东西。
当然要记住,这样的写法并不是完全不可取的。。在需要的场合,很大程度上这样是一个不错的解决方式。
义公用、静态的变量来实现一个全局变量。例如 : Class GlobalVar{
public static global_var;
} 在类 GlobalVar中定义变量 global_var为 public stat-ic,使得其它类
可以访问和修改该变量。 =========================================
这是全局变量的定义,如果有可能的话,尽量使用局部变量为好
唉,这个其实没有什么好讨论的,它应该在哪里就在哪里。
如果真的比较困惑,还有个办法可以分辨,放在哪里你用起来觉得自然就对了。
不会不会,挺好的。。对了,俺帮你画张图吧:
+-----------+
a T_T l a ^_^ a l
+-----------+
再灌下去,xiaozuidazhi (以前不会用,导致信誉分低_我是好人!) 肯定要踢俺了。=.=突然发现,楼主的ID和俺的好像~~
该用全局的就用全局的。
单件的模式应该相当于全局变量的模拟,如果它就是全局唯一的而且是经常被引用的,你能让他局部化吗?这样作的话只会影响效率和导致差的设计,当然同时要也要考虑这个单件的大小对内存的影响。我想类内的情形也差不多! 局部变量需要一个快的cpu,全局变量需要一个大的内存,呵呵,各位以为呢。
在java中也不存在全局变量的概念.
如果是全局的就用单例.
全局变量会导致使用的扩散,无法控制对该变量的调用.
而且对于现在的趋势,硬件的成本远远低于软件的成本.
号外:我怎么一看到 ConfigLoader就感觉这么熟呢 ^_^
现成立“面向对象编程中变量使用ISO9000标准”委员会,开始接受报名!
jvm中对函数调用中实例变量和局部变量的操作处理不同.
"实例变量"类中所有成员的函数都使用同一个引用.所以函数并行调用会互相影响.
而"局部变量",当函数被调用时,jvm会为函数开辟一个独立的statck frame,并在这里存放局部变量的分配空间,调用完成后statck frame就释放,由于相同函数使用独立的stack frame,所以并行调用不会互相影响.
所以说"实例变量"使用是线程不安全,而局部变量的使用是线程安全.如果你的应用程序需要线程安全的操作,建议不要使用实例变量.当然你可以用synchorize,但这需要付出代价.