博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java的单例、static修饰符及static的继承
阅读量:6640 次
发布时间:2019-06-25

本文共 5275 字,大约阅读时间需要 17 分钟。

单例设计模型:

static修饰符:

①:static静态只有一份(同一个虚拟机中) (节省资源),类代码被装载内存时,静态代码分配内存,并执行,并且常驻内存。

可参考:

②:Static修饰成员变量,成为"类变量",属于整个类,类的共享变量。注:不能修饰局部变量。

         static是一块为整个类共有一块存储区域,静态变量只有一份,值变化后,所有访问值变化生效。

         java中用类名调用static变量和方法(对象调用也可以):类名.变量(方法名)

③:static修饰类方法,属于类方法,继承中子类可以定义相同方法,静态不支持覆盖,此时不存在继承间的多态。

④:static静态块(定义和方法平行),在类加载时执行一次,以后不再执行,一般用于初始化静态成员。

④:类的方法继承与否取决于4大访问修饰符,和static修饰符无关(static不会发生继承多态)。

        注:main()主方法定义成static,是因为加载类代码入内存的时候还没有对象这个概念。

类A:

package ca.singleton;public class A {	//static属性	public static int a = 5;	//实例变量	public int b = 3;	public static String c;	//静态块	static{		c="initial c field";	}	//静态方法	public static void print(){		System.out.println("A static print method");	}	//实例方法	public void display(){		System.out.println("A instance display method");	}}
类B继承A:
package ca.singleton;public class B extends A{	//static属性	public static int a = 2;	//实例变量	public int b = 8;	public static String c;	//静态块	static{		c="initial xxxxx";	}	//静态方法	public static void print(){		System.out.println("B static print method");	}	//实例方法	public void display(){		System.out.println("B instance display method");	}	public static void main(String[] args) {		B b = new B();		A a = new B();		//call static print method		b.print();		a.print();		//call instance display method		b.display();		a.display();		//field static		System.out.println(b.a);		System.out.println(a.a);		//field instance		System.out.println(b.b);		System.out.println(a.b);		//static block		System.out.println(b.c);		System.out.println(a.c);	}}
输出结果为:

B static print method

A static print method
B instance display method
B instance display method
2
5
8
3
initial xxxxx
initial c field

static继承:

从上面执行结果,可以反映出:

①:静态属于所有它的类,不会被继承。

②:类的继承层次模型下的多态只发生在方法(成员方法)上。

③:类的成员属性,以及静态变量,静态方法,静态块,都不发生继承。

Singleton模型:

Static通常用于单例设计,Singleton是一种设计模式,高于语法,可以保证一个类在整个系统中(同一个虚拟机中)仅有一个对象。

在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例,具有资源管理器功能。

单例类原则:  ①只有一个实例对象;  ②自己创建自己的这一个对象;  ③通过方法提供仅有的对象给其他对象使用。

                  综之:  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

实现的三种方式:

1:饿汉式单例

package ca.singleton;/** * 饿汉式单例类 * 单例类被第一次装载入内存时候,已经产生了单例对象 * */public class SingletonA {	//在类初始化时(装载类时,非new),单例对象,已经被初始化	private static SingletonA instance = new SingletonA();	//默认构造方法为私有,防止其他地方实例化	private SingletonA(){}	//静态工厂方法,对外提供获取单例对象的获取接口	/**	 * 获取SingletonA类的单例对象	 * */	public static SingletonA getInstance(){		return instance;	}}
2:懒汉式单例类

package ca.singleton;/** * 懒汉式单例类 * 延迟(懒)加载,在第一次调用getInstance()方法获取单例对象的时候创建单例对象 * */public class SingletonB {	//其他类第一次获取单例对象时候创建	private static SingletonB instance = null;	//默认构造方法为私有,防止其他地方实例化	private SingletonB(){}	//静态工厂方法,对外提供获取单例对象的获取接口	/**	 * 获取SingletonB类的单例对象	 * */	public synchronized static SingletonB getInstance(){		if(instance == null){			instance = new SingletonB();		}		 return instance;	}}
3:登记式单例类

package ca.singleton;import java.util.HashMap;import java.util.Map;/** * 登记式单例类 * 使用类名注册,下次直接从里面获取 * */public class SingletonC {	//登记类,键值对(类名- 类对象)保存map   ?if SingletonC = Object	private static Map
map = new HashMap
(); //提供protected的默认构造方法, 同包或子类可见 protected SingletonC() {} //注册当前类的对象到map static{ SingletonC scInstance = new SingletonC(); map.put(scInstance.getClass().getName(), scInstance); } /** * 静态工厂方法,返回类在map中被登记的唯一实例 * */ public static SingletonC getInstance(String name){ //name输入为空,使用当前类名称 if(name == null){ name = SingletonC.class.getName(); System.out.println("name is null,name to "+name); } //name类名对应的对象未被登记到map if(map.get(name) == null){ try { map.put(name,(SingletonC) Class.forName(name).newInstance()); } catch (InstantiationException e) { System.out.println("Instantiation Exception"+e); } catch (IllegalAccessException e) { System.out.println("Illegal Access Exception"+e); } catch (ClassNotFoundException e) { System.out.println("Class Not Found Exception"+e); } } return map.get(name); } //一个示意性的商业方法??? public String about(){ return "Hello,I am a schematic of the commercial method"; }}
singletonD继承singletonC:

package ca.singleton;public class SingletonD extends SingletonC{	}
测试类:

package ca.singleton;public class SingleTest extends A {	public static void main(String[] args) {		//		SingletonA s1 = SingletonA.getInstance();		SingletonA s2 = SingletonA.getInstance();		String ss = s1==s2 ? "1&2 T" : "1&2 F";		System.out.println(ss); 		//		SingletonB s3 = SingletonB.getInstance();		SingletonB s4 = SingletonB.getInstance();		System.out.println(s3==s4 ? "3&4 T" : "3&4 F"); 		//		SingletonC s5 = SingletonC.getInstance(null);		SingletonC s6 = SingletonC.getInstance(null);		System.out.println(s5==s6 ? "5&6 T" : "5&6 F");		System.out.println(s5.about());				SingletonD s7 = (SingletonD) SingletonC.getInstance("ca.singleton.SingletonD");		SingletonD s8 = (SingletonD) SingletonC.getInstance("ca.singleton.SingletonD");		System.out.println(s7==s8 ? "7&8 T" : "7&8 F");		System.out.println(s7.about());		System.out.println(s5==s7 ? "5&7 T" : "5&7 F");	}}

输出结果为:

1&2 T

3&4 T
name is null,name to ca.singleton.SingletonC
name is null,name to ca.singleton.SingletonC
5&6 T
Hello,I am a schematic of the commercial method
7&8 T
Hello,I am a schematic of the commercial method
5&7 F

从上面执行结果,可以反映出:

使用“==”比较,基本类型,引用存储空间直接存储的真实值,所以比较的值;

对于其他类类型,在任何时候“==”比较的都是地址,这种比较永远不会被覆盖。

可以看出上边的单例都存在一个对象。

如果想让高并发下多线程在单例中生效,就要保证单例对象操作的方法为线程同步(对象锁)。

转载地址:http://sapvo.baihongyu.com/

你可能感兴趣的文章
发现和使用OneNote的计算器功能
查看>>
倾听是谈话中最基本的技巧
查看>>
使用Cocos2d-x 和粒子编辑器实现“天天爱消除”场景特效
查看>>
解决在VS2008中“当前不会命中断点,源代码与原始版本不同”的问题
查看>>
#include "stdafx.h" 错误?
查看>>
getResource()和getResourceAsStream的路径问题
查看>>
在VC中定制Doxygen注释宏
查看>>
debian下安装wps office
查看>>
java 获取网络servelt 返回下载文件大小
查看>>
jsp中动态include与静态include的区别
查看>>
【原】unity3D 调用android .so
查看>>
LibreOffice 3.6.6 修复了 50 个 Bug
查看>>
PHREL 1.0.1 发布,主机流量限制工具
查看>>
动画骨骼【Visual C++】游戏开发五十二 浅墨DirectX教程二十 骨骼动画来袭(一)...
查看>>
【ASP.NET 基础】用户控件开发
查看>>
pgbench的使用简介
查看>>
Delphi 指针数组的引用
查看>>
如何在Apache中建立一个新端口
查看>>
谈谈用ASP.NET开发的大型网站有哪些架构方式(成本)
查看>>
地址请求Eclipse中TCPIPMonitor的用法
查看>>