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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© study123 初级黑马   /  2013-8-29 15:52  /  3916 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 study123 于 2013-8-30 14:56 编辑

public class Singleton{
        private Singleton(){}
        private static Singleton instance = new Singleton();
        public static Singlton getInstance(){
                return instance;
        }
}
上述代码中的构造函数为什么是private的呢,这样有什么作用?虽然是无参的,但是加了作用域,还算是系统默认的构造函数吗?
还有下面new对象的代码,都private了,为什么还要加static呢?

评分

参与人数 1技术分 +1 收起 理由
张智文 + 1

查看全部评分

14 个回复

倒序浏览
本帖最后由 杨成 于 2013-8-29 16:32 编辑

这是恶汉式的单例设计模式。
private static Singleton instance = new Singleton();
static和=号后面的保证程序一运行,当本类一加载,就实例化了一个Singleton对象,而且在内存中是唯一的。就只等着你在主函数中通过Singleton.getInstance()来返回已经实例化好的对象的引用。

而懒汉式的
public static Singlton getInstance(){
                return new Singleton();
        }

这样是在程序一运行,类一加载,但是对象实例化要等到你在主函数中通过Singlton.getInstance()才开始创建对象并返回引用。


这两种方式的区别就是:前者是程序一运行这个对象就已经建立了,后者是你啥时候调用静态方法getInstance(),啥时候才建立对象。

就是这样!

评分

参与人数 1技术分 +1 收起 理由
张智文 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 杨成 于 2013-8-29 16:33 编辑

构造函数私有化,这样你外部就不能通过new Singleton()建立对象了。只能通过本类提供的静态方法返回建立的对象。
static是为了保证在内存中的唯一性,被声明的成员属于类,而不属于对象。要不怎么叫单例呢?怎么保证唯一性呢?

回复 使用道具 举报
1.私有化的构造函数,外部不能new出来的。既然不能new出来,也就无法用对象来调用成员了。
2.static修饰的是一个本类的对象,看到static你就联想到是在内存之中的共享区(或者静态区)中,不加static这个成员虽然私有,但是还是可以通过特殊的方法来访问。对象并没有唯一性。实际上,单例模式还真不一定绝对的保证对象的唯一性。你想下,如果不用static修饰,怎么调用这个类中的成员?也因此,下面的那个公共的方法也是static修饰的,想到static,联想到共享和类名调用,不会错。个人理解,不代表大家的立场。

评分

参与人数 1技术分 +1 收起 理由
薛鹏鹏 + 1

查看全部评分

回复 使用道具 举报
类中是有默认的构造函数的如果自己定义的话,就会覆盖默认的构造函数。它是为对象初始化的。。
private是私有化的意思,对代码进行了封装,不能被直接调用,
static应该说是方便被调用吧。
回复 使用道具 举报
static   用这个关键字修饰后随着类而加载,能被所有对象所共享、可以直接被类名调用
回复 使用道具 举报
meng 高级黑马 2013-8-29 19:09:40
7#
static: 关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。
特点:
1,想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。
2,被静态修饰的成员,可以直接被类名所调用。也就是说,静态的成员多了一种调用方式。类名.静态方式。
3,静态随着类的加载而加载。而且优先于对象存在。

作用:可以完成类的初始化。静态代码块随着类的加载而执行,而且只执行一次(new 多个对象就只执行一次)。如果和主函数在同一类中,优先于主函数执行

静态代码块、构造代码块、构造函数同时存在时的执行顺序:静态代码块 ——>> 构造代码块 ------>> 构造函数;

单例设计模式:
解决的问题:保证一个类在内存中的对象唯一性。
比如:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。

Runtime()方法就是单例设计模式进行设计的。

如何保证对象唯一性呢?
思想:
1,不让其他程序创建该类对象。
2,在本类中创建一个本类对象。
3,对外提供方法,让其他程序获取这个对象。

步骤:
1,因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法再创建该类对象;
2,就在类中创建一个本类的对象;
3,定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。(作用:可控)

代码体现:
1,私有化构造函数;
2,创建私有并静态的本类对象;
3,定义公有并静态的方法,返回该对象。
---------------------------------------------
//饿汉式
class Single{
        private Single(){} //私有化构造函数。
private static Single s = new Single(); //创建私有并静态的本类对象。
        public static Single getInstance(){ //定义公有并静态的方法,返回该对象。
                return s;
        }
}
---------------------------------------------
//懒汉式:延迟加载方式。
class Single2{
        private Single2(){}
private static Single2 s = null;
        public static Single2 getInstance(){
                if(s==null)
                        s = new Single2();
                return s;
        }
}

评分

参与人数 1技术分 +1 收起 理由
薛鹏鹏 + 1

查看全部评分

回复 使用道具 举报
雷鬼 发表于 2013-8-29 17:50
1.私有化的构造函数,外部不能new出来的。既然不能new出来,也就无法用对象来调用成员了。
2.static修饰的 ...

private的作用域是当前类,即使不用static修饰,在该类中还是可以调用这个类中的成员,private static Singleton instance = new Singleton();为什么还要加static呢?
回复 使用道具 举报
meng 发表于 2013-8-29 19:09
static: 关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。
特点:
1,想要实现对象中的共性数据 ...

懒汉式里面要加个锁吧,你那种写法还是不能保证只有一个实例吧?
回复 使用道具 举报
private 方便封装,static 关键字表示在程序加载时,程序已经加载到内存,方便调用,适于用在整个程序运行期间都用到的方法

评分

参与人数 1技术分 +1 收起 理由
薛鹏鹏 + 1

查看全部评分

回复 使用道具 举报
如果您的问题已经解决
请更改分类未解决为已解决
保持队形,谢谢合作

详情参考 如何修改分类

回复 使用道具 举报
这是单例设计模式的饿汉式 构造函数被private修饰时为了不让其他类去构造Singleton类的对象, 系统默认的是什么构造函数都不i写,它才有默认的. 静态方法getInstance()只能访问静态的成员
回复 使用道具 举报
study123 发表于 2013-8-29 21:11
懒汉式里面要加个锁吧,你那种写法还是不能保证只有一个实例吧?

老师说的,在涉及多线程的知识的时候,懒汉式设计模式不一定绝对保证单一性的。具体看视频教程哦。我认为你看得太粗糙了,慢一点效果会更好。锁是后面线程的知识,面向对象的知识是核心,是重中之重。体会思想是最重要的,个人也认为,JAVA基础的难点在面向对象思想的体会。
回复 使用道具 举报
study123 发表于 2013-8-29 20:44
private的作用域是当前类,即使不用static修饰,在该类中还是可以调用这个类中的成员,private static Si ...

private 是来封装数据的,让外部看不到这个成员的。构造函数私有化了,就不能new出对象来了,就不能通过new出对象来调用成员,外部只能够通过类名来调用,你不定义静态的,你怎么调用?本类之中的方法怎么返回本类对象?看看视频啊,里面老师讲的很详细。
回复 使用道具 举报
虚拟机会首先加载带有static的方法,所以可以直接调用类singleton中的getinstance()方法,若是方法都没有被虚拟机加载又怎么可能直接调用呢!我是这么理解的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马