A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 乔青山 于 2014-2-27 11:53 编辑

刚才看到一同学问道下面这种写法可不可以:class Single {
        private Single(){}
        public static Single a = new Single();        
}
第一反应感觉这种写法每次调用a的时候都会实例化一个新的对象。于是写了个小程序测试:
class TestSingle{
        public static void main(String[] args){
                System.out.println(Single.a);
                System.out.println(Single.a);
        }
}
class Single {
                        private Single(){}
                       public static Single a = new Single();        
}
结果发现,输出的地址是一样。于是就凌乱了。。。百度谷歌一番,又思索了一番后:
感觉其实public static Single a = new Single();就和public static int num = 1;一样。
在执行这句代码的时候内存已经把a的引用确定了,所以之后的每次调用都不会再实例化了。
然而~百度谷歌中发现了这个http://callmegod.iteye.com/blog/1474441
这里面讲到了这么一个写法:
public class MaYun {
        private MaYun(){}
        public static final MaYun instance = new MaYun();
}
发现和上面写法差不多,唯一的区别是这个用final修饰了对象,有一番百度谷歌后查阅到:
final修饰的对象,引用不变,但是引用的内容仍然可变。个人理解就是只能指向一个空间,空间里的内容可变。
那问题来了:
不加final的时候测试对象就是一个,那这个final岂不是加的有些浪费?
不可以给instance重新定义对象?构造器是私有的,类外本来就不可能再定义对象了,怎么还给给instance重新定义呢?
保证每次调用的是同一个对象?不加final每次调用的也是同一个对象,同样可以保证
final的作用体现在什么地方?


评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

10 个回复

倒序浏览
饿汉式加final安全好用。不加final的话可以通过反射技术让对象不唯一;加了final的话不能通过反射再对其进行重新赋值。

点评

e.c
基本上都饿汉都固定写上final的吧。值一出现就是唯一的。  发表于 2014-2-27 11:31
回复 使用道具 举报
e.c 发表于 2014-2-27 11:28
饿汉式加final安全好用。不加final的话可以通过反射技术让对象不唯一;加了final的话不能通过反射再对其进 ...

额。。。好吧,反射还没有学到,学到那的时候我再想想这个问题。。。
回复 使用道具 举报
首先单例绝对不会你这样写:
class Single {
                        private Single(){}
                       public static Single a = new Single();        
}
你这样的话那么外面不就可以直接改变你a的值么?
所以加final没浪费啊,加了不就可以让a的值,不可以改变吗?
回复 使用道具 举报 1 0
jkenny 发表于 2014-2-27 18:03
首先单例绝对不会你这样写:
class Single {
                        private Single(){}

改变不了,因为构造器私有,外面不能实例化
回复 使用道具 举报
乔青山 发表于 2014-2-27 18:28
改变不了,因为构造器私有,外面不能实例化

大哥可是你的a是静态的啊。。。
下面代码你去执行下看看结果:
  1. class Single {
  2.         private Single(){}
  3.         public static Single a = new Single();        
  4. }

  5. public class Test
  6. {
  7.         public static void main(String[] args)
  8.         {
  9.                 System.out.println(Single.a);
  10.                 Single.a=null;
  11.                 System.out.println(Single.a);
  12.         }
  13. }
复制代码
回复 使用道具 举报
jkenny 发表于 2014-2-27 21:48
大哥可是你的a是静态的啊。。。
下面代码你去执行下看看结果:

。。。。除了null是不可能给a重新定义一个对象的
回复 使用道具 举报
jkenny 发表于 2014-2-27 21:48
大哥可是你的a是静态的啊。。。
下面代码你去执行下看看结果:

另外,null也不是对象,把a变为空了,那这个a就调用不了类中的方法了,那a还有什么意义,加final是为了防止用户做没意义的事?我没事干定为空,也不调用方法,就定个空在那放着。。。
回复 使用道具 举报
jkenny 中级黑马 2014-2-27 23:46:25
9#
乔青山 发表于 2014-2-27 22:02
另外,null也不是对象,把a变为空了,那这个a就调用不了类中的方法了,那a还有什么意义,加final是为了防 ...

好把,也有道理。。
回复 使用道具 举报
class Single {
                        private Single(){}
                       public static Single a = new Single();        
}
加final与不加final的确是有区别的,
学习类
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马