栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

关键字:static和单例模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关键字:static和单例模式

关键字static的引入:       当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上 的对象,只有通过 new 关键字才会产生出对象,这时系统才会分配内存空间给对象, 其方法才可以供外部调用。      我们有时候希望无论是否产生了对象或无论产生了多少 对象的情况下, 某些特定的数据在内存空间里只有一份 ,例如所有的中国人都有个 国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中 都单独分配一个用于代表国家名称的变量。

 * static 关键字的使用

   1.static:静态的
 * 2.static可以用来修饰:属性、方法、代码块、内部类
 * 3.使用static修饰属性:静态变量(类变量) 
 *         3.1属性:按是否使用static修饰,又分为:静态属性  和  非静态属性(实例变量)
 *         实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改
           静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的
 *         3.2static修饰属性的其他说明:
 *             ①静态变量随着类的加载而加载,可以通过“类.静态变量”的方式进行调用
 *             ②静态变量的加载要早于对象的创建 
 *             ③由于类只会加载一次,则静态变量在内存中也只会存在一份,存在方法区的静态域中
 *                     类变量       实例变量
 *     ④ 类           yes            no
 *       对象           yes                 yes
 * 

类变量 vs 实例变量内存解析

 * 4.使用static修饰方法: 静态方法

        ①随着类的加载而加载,可以通过“类.静态方法”的方式进行调用

       ②在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。

        静态方法中,只能调用静态的方法或属性;非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性

        ③static注意点:在静态的方法内,不能使用this关键字、super关键字

关于静态方法、静态属性的使用,大家都从生命周期的角度去解释。 

 5.开发当中,如何确定一个属性是否要声明为static

属性是可以被多个对象共享,不会随着对象的不同而不同的类中的常量也往往设置成static

  开发之中 如何确定一个方法是否要声明为static

操作静态属性的方法,通常设置为static工具类中的方法,习惯上声明为static的   比如Math、Arrays、Collections等   单例 (Singleton)设计模式  设计模式 是在大量的实践中总结和理论化之后优选的代码结构、编程风格、 以及解决问题的思考方式 。设计模式免去我们自己再思考和摸索。就像是经典 的棋谱,不同的棋局,我们用不同的棋谱。 ” 套路 ”

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对   某个类 只能存在一个对象实例 ,并且该类只提供一个取得其对象实例的方法。

如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构 造器的访问权限设置为 private ,这样,就不能用 new 操作符在类的外部产生 类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无 法得到类的对象,只能 调用该类的某个静态方法 以返回类内部创建的对象, 静态方法只能访问类中的静态成员变量,所以,指向类内部产生的 该类对象 的变量也必须定义成静态的 。 单例模式的实现方式一:饿汉式

//饿汉式
class Bank{
    //1.私有化类的构造器 为了避免在Bank类的外面去调用构造器
    private Bank(){
        
    }
    //2.内部里面创建类的对象
    //4.要求此对象也必须声明为静态的
    private static Bank b1 = new Bank();
    //3.提供公共的静态方法,返回类的对象
    public static Bank getInstance(){
        return b1;
    }    
}

完整代码描述 :

package com.hlq.singlemodel;

public class SingleTest1 {
	public static void main(String[] args) {
//		想在这里面用b1这个对象    需要在Bank里提供方法返回类的对象
		Bank bank1 = Bank.getInstance(); //bank1和bank2是同一个对象
		Bank bank2 = Bank.getInstance();
		System.out.println(bank1==bank2);
	}
}
//饿汉式
class Bank{
	//1.私有化类的构造器 为了避免在Bank类的外面去调用构造器
	private Bank(){
		
	}
	//2.内部里面创建类的对象
	//4.要求此对象也必须声明为静态的
	private static Bank b1 = new Bank();
	//3.提供公共的静态方法,返回类的对象
	public static Bank getInstance(){
		return b1;
	}	
}
 单例模式的实现方式一:懒汉式

//懒汉式
class Order{
    //1.私有化类的构造器
    Order(){
        
    }
    //2.声明当前类对象,没有初始化
    //4.此对象也必须声明为static
    private static Order o1 = null;
    
    //3.声明一个public、static的返回当前类对象的方法
    public static Order getInstance(){
        if(o1 == null){
            o1 = new Order();
        }
        return o1;
        
    }
    
}

完整代码描述 :

package com.hlq.singlemodel;

public class SingleTest2 {
	public static void main(String[] args) {
		Order order1 = new Order();
		Order order2 = new Order();
		System.out.println(order1==order2);//true
		
	}
}
//懒汉式
class Order{
	//1.私有化类的构造器
	Order(){
		
	}
	//2.声明当前类对象,没有初始化
	//4.此对象也必须声明为static
	private static Order o1 = null;
	
	//3.声明一个public、static的返回当前类对象的方法
	public static Order getInstance(){
		if(o1 == null){
			o1 = new Order();
		}
		return o1;
		
	}
	
}

单例模式记忆技巧: 

什么时候用什么时候造(new)  这是懒

先造为饿(一开始就new好了)

区分饿汉式和懒汉式:

饿汉式(会写):

        好处: 线程天然安全的

        坏处 :对象加载时间过长。

懒汉式(会写):

        好处 :  延迟对象的创建。

        坏处:目前的写法线程不安全

单例模式的优点:  由于单例模式只生成一个实例, 减少了系统性能开销 ,当一个对象的 产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可 以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方 式来解决。 单例(Singleton)设计模式-应用场景

 网站的计数器,一般也是单例模式实现,否则难以同步。  应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志 文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库 资源。

项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置 文件数据,都生成一个对象去读取。

Application 也是单例的典型应用 Windows的Task Manager (任务管理器)就是很典型的单例模式 Windows的Recycle Bin (回收站)也是典型的单例应用。在整个系统运行过程 中,回收站一直维护着仅有的一个实例。

练习:
package com.hlq.staticexer;

public class CircleTest {
	public static void main(String[] args) {
		Circle c1 = new Circle();
		System.out.println("圆c1的编号:" + c1.getId());
		Circle c2 = new Circle();
		System.out.println("圆c2的编号:" + c2.getId());
		Circle c3 = new Circle(2.3);
		System.out.println("圆c3的编号:" + c3.getId());
		System.out.println("创建圆的个数:" + Circle.getTotal());
		
	}

}
class Circle{
	private double radius;
	private int id;//编号    要求自动赋值
	private static int total;//造了多少个圆的对象  记录圆的个数
	private static int init = 1001;//static声明的属性被多个对象所共享
	public Circle(){
		id = init++;
		total++;
	}
	public Circle(double radius){
		this();
//		id = init++;
//		total++;
		this.radius = radius;
	}
	public double findArea(){
		return 3.14*radius*radius;
	}
	public int getId() {
		return id;
	}
	public static int getTotal() {
		return total;
	}
	public static int getInit() {
		return init;
	}
	
}

练习二: 

编写一个类实现银行账户的概念,包含的属性有“帐号”、“密 码”、“存款余额”、“利率”、“最小余额”,定义封装这些 属性的方法。 账号要自动生成。 编写主类,使用银行账户类,输入、输出 3 个储户的上述信息。 考虑:哪些属性可以设计成 static 属性。
package com.hlq.staticexer;

public class Account {
	private int id;
	private String password = "123456";
	private double balance;
	private static double interestRate;
	private static double minMoney = 1.0;
	private static int init = 1001;
	public Account(){
		id = init++;
		
	}
	public Account(String password,double balance){
		this();
		this.password = password;
		this.balance = balance;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public static double getInterestRate() {
		return interestRate;
	}
	public static void setInterestRate(double interestRate) {
		Account.interestRate = interestRate;
	}
	public static double getMinMoney() {
		return minMoney;
	}
	public static void setMinMoney(double minMoney) {
		Account.minMoney = minMoney;
	}
	public int getId() {
		return id;
	}
	public double getBalance() {
		return balance;
	}
	@Override
	public String toString() {
		return "Account [id=" + id + ", password=" + password + ", balance=" + balance + "]";
	}
	
	
}
package com.hlq.staticexer;

public class AccountTest {
	public static void main(String[] args) {
		Account acc1 = new Account();
		Account acc2 = new Account("654321",50000);
		Account.setInterestRate(0.0123);
		Account.setMinMoney(1000);
		System.out.println(acc1);
		System.out.println(acc2);
		System.out.println(acc1.getMinMoney());
		System.out.println(acc1.getInterestRate());
		
	}

}

        

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/770086.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号