static关键字、单例模式

面向对象学习day17

往往在逃避命运的路上,会与之不期而遇。

一、static关键字

1、说明

  • static:静态的

  • static可以用来修饰:属性、方法、代码块、内部类

2、使用static修饰属性:静态变量(或类变量)

2.1 按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)

  • 实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个对象中非静态属性时,不会导致其他对象中同样的属性值的修改。

  • 静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。

2.2 static修饰属性的其他说明

  • 静态变量随着类的加载而加载。可以通过“类.静态变量”的方式调用

  • 静态变量的加载要早于对象的创建

  • 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。

  • 类变量 实例变量

    类 yes no

    对象 yes yes

2.3 静态属性举例

System.out 、Math.PI

2.4 实例代码

 package Object.day17;
 ​
 public class StaticTest {
     public static void main(String[] args) {
 ​
         Chinese.nation = "中国";
 ​
         Chinese c1 = new Chinese();
         c1.name = "周星驰";
         c1.age = 18;
         c1.nation = "CHN";
 ​
         Chinese c2 = new Chinese();
         c2.name = "柴静";
         c2.age = 16;
         c2.nation = "Chinese";
 ​
         System.out.println(c1.nation); //Chinese
     }}
 ​
 class Chinese{
 ​
     String name;
     int age;
     static String nation;
 ​
 }

2.5 实例内存解析

3、使用static修饰方法:静态方法

3.1 说明

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

  • 类变量 实例变量

    类 yes no

    对象 yes yes

  • 静态方法中,只能调用静态的属性或方法

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

3.2 static注意点

  • 在静态方法中,不能使用this关键字、super关键字(都还没有对象呢~)

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

4、开发中,如何确定一个属性是否要声明为static的?

  • 属性时可以被多个对象所共享的,不会随着对象的不同而不同。

  • 类中的常量也常常声明为static

5、开发中,如何确定一个方法是否要声明为static的?

  • 操作静态属性的方法,通常设置为static的

  • 工具类中的方法,习惯上声明为static的。比如:Math、Arrays、Collections

6、static实例一

 
package Object.day17;
 ​
 public class CircleTest {
     public static void main(String[] args) {
 ​
         Circle c1 = new Circle();
         Circle c2 = new Circle();
         Circle c3 = new Circle(3.4);
 ​
         System.out.println("c1的id:" + c1.getId());
         System.out.println("c2的id:" + c2.getId());
         System.out.println("c3的id:" + 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();
         this.radius = radius;
     }
 ​
     public double getRadius() {
         return radius;
     }
 ​
     public void setRadius(double radius) {
         this.radius = radius;
     }
 ​
     public int getId() {
         return id;
     }
 ​
     public void setId(int id) {
         this.id = id;
     }
 ​
     public double findArea(){
         return 3.14 * radius * radius;
     }
 ​
     public static int getTotal() {
         return total;
     }
 ​
     public static void setTotal(int total) {
         Circle.total = total;
     }
 }

result:

7、static实例二

题目:

代码:

package Object.day17;
 ​
 public class CircleTest {
     public static void main(String[] args) {
 ​
         Circle c1 = new Circle();
         Circle c2 = new Circle();
         Circle c3 = new Circle(3.4);
 ​
         System.out.println("c1的id:" + c1.getId());
         System.out.println("c2的id:" + c2.getId());
         System.out.println("c3的id:" + 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();
         this.radius = radius;
     }
 ​
     public double getRadius() {
         return radius;
     }
 ​
     public void setRadius(double radius) {
         this.radius = radius;
     }
 ​
     public int getId() {
         return id;
     }
 ​
     public void setId(int id) {
         this.id = id;
     }
 ​
     public double findArea(){
         return 3.14 * radius * radius;
     }
 ​
     public static int getTotal() {
         return total;
     }
 ​
     public static void setTotal(int total) {
         Circle.total = total;
     }
 }

 package Object.day17;
 ​
 public class AccountTest {
     public static void main(String[] args) {
         Account a1 = new Account();
         Account a2 = new Account("123456",4000);
 ​
         System.out.println(a1);
         System.out.println(a2);
     }
 }

二、单例模式

1、定义:

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

2、 实现基本流程

  1. 私有化类的构造器

  2. 内部创建类的对象

  3. 调用公共的静态的方法,返回类的对象

  4. 要求此前的对象也必须声明为静态的

3、具体代码

3.1 饿汉式

 package Object.day17.Singleton;
 //单例模式的饿汉式实现
 public class SingletonTest1 {
     public static void main(String[] args) {
         Bank bank1 = Bank.getInstance();
         Bank bank2 = Bank.getInstance();
         System.out.println(bank1 == bank2);
     }
 }
 ​
 //饿汉式
 class Bank{
 ​
     //1.私有化类的构造器
     private Bank(){
     }
 ​
     //2.内部创建类的对象
     //4.要求此对象也必须声明为静态的
     private static Bank instance = new Bank();
 ​
     //3.调用公共的静态的方法,返回类的对象
     public static Bank getInstance(){
         return instance;
     }
 ​
 }

3.2 懒汉式

 
package Object.day17.Singleton;
 //单例模式的懒汉式实现
 public class SingletonTest2 {
     public static void main(String[] args) {
         Order order1 = Order.getInstance();
         Order order2 = Order.getInstance();
         System.out.println(order1 == order2);
     }
 }
 ​
 class Order{
     //1.私有化构造器
     private Order(){
     }
     
     //2.声明当前类的对象,没有初始化
     //4.要求此对象也必须声明为静态的
     private static Order instance = null;
 ​
     //3.调用公共的静态的方法,返回类的对象
     public static Order getInstance(){
         if(instance == null){
             instance = new Order();
         }
         return instance;
     }
 }

4、区分饿汉式与懒汉式

饿汉式:

  • 坏处:对象的加载时间过长

  • 好处:饿汉式是线程安全的

懒汉式:

  • 好处:延迟对象的创建

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

5、单例模式应用场景

  • 网站的计数器,实现同步

  • 应用程序的日志应用

  • 数据库连接池

  • 读取配置文件的类

  • Application

  • Windows 的Task Manager(任务管理器)

  • Windows的 Recycle Bin(回收站)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单例模式是一种设计模式,它的目的是确保一个类只有一个实例,并提供全局访问该实例的方式。 在单例模式中,使用static标记的flag是一种常见的实现方式。这个flag通常用来标记当前的实例是否已经被创建。 具体实现时,可以在类的静态属性中定义一个私有静态变量flag,并初始化为false。当需要访问单例实例时,先通过一个公共静态方法来检查flag的状态,如果flag为false,则表示实例尚未被创建,可以使用new关键字创建一个新的实例,并将flag设置为true。如果flag为true,则表示实例已经存在,直接返回该实例。 以下是一个简单的示例代码: ```java public class Singleton { private static boolean flag = false; private static Singleton instance; private Singleton() { // 私有构造方法,防止外部通过new关键字创建实例 } public static synchronized Singleton getInstance() { if (!flag) { instance = new Singleton(); flag = true; } return instance; } } ``` 以上代码中,使用flag来标记实例是否已经存在,在getInstance方法中首先检查flag的状态,如果为false,则进行实例的创建。在多线程环境下,为了保证线程安全,可以在getInstance方法上加上synchronized关键字,确保只有一个线程能够进入创建实例的逻辑。 通过这种方式,使用static flag可以更加直观地判断实例是否已经存在,避免了重复的实例创建。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值