深入了解static关键字的作用和应用--java面向对象学习

news2024/11/14 20:14:15

Static修饰成员变量

Static是什么

  • 叫静态,可以修饰成员变量,成员方法                    

 成员变量按有无static修饰分俩种:

  • 类变量:有static修饰,属于类,在计算机里只有一份,会被类的全部对象共享
  • 实例变量(对象的变量):无static修饰,属于每个对象的

 类变量为所有对象共享,类变量的生命周期同类一样,而每个对象都有独属于自己的示例变量,实例变量的生命周期同对应实例一样,公家的和自家的区别

访问类变量的方式:

  • 类名.类变量(推荐,高效,方便)
  • 对象.类变量(不推荐

    ——通过类名访问相当于直接去方法区找到类和对应类方法,而通过对象访问是先找到对象再通过对象去找类,再找到对应类方法

 代码演示:

  • 创建一个学生类:
    public class Student {
        static int grade;    //年级
        String name;    //姓名
    }
  • 创建俩个学生对象:
    public class StaticDemo1 {
        public static void main(String[] args) {
            Student s1 = new Student(); //定义学生对象1
            Student s2 = new Student(); //定义学生对象2
    
            Student.grade = 1;  //通过类名访问类变量,给类变量grade赋值
    //        s1.grade = 2; //也可以通过对象来访问类变量,不过不推荐这麽做
    
            s1.name = "小明"; //学生对象1实例变量赋值
            s2.name = "小红"; //学生对象2示例变量赋值
    
            System.out.println("我是" + Student.grade +"年级的" + s1.name);  //输出学生对象1和学生对象2的信息
            System.out.println("我是" + Student.grade +"年级的" + s2.name);
        }
    }

注:实例变量不能通过类名去访问

像这种访问方式是错误的,因为实例变量独属于每个对象,只通过类名怎么知道你是想访问哪个对象呢~

类变量的应用场景

  •  在开发中,如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住

案例: 

  • 有一个学生类,希望学生类可以自己记录已经创建过多少学生对象
public class Student2 {
    public static int number; //记录已经创建多少个学生对象

    public Student2() {
        //在同一个类中,访问自己类的类变量可以不写类名,在别的类中需要写类名
        number++; //每次调用构造函数,都记录下来
    }
}
public class StaticDemo2 {
    public static void main(String[] args) {
        Student2 s1 = new Student2();
        Student2 s2 = new Student2();
        Student2 s3 = new Student2();

        System.out.println("我已经创建了" + Student2.number + "个学生对象啦");
    }
}

运行结果:


Static修饰成员方法

成员方法按有无Static修饰分俩种

  • 类方法:有Static修饰的成员方法,属于类
  • 实例方法:无Static修饰的成员方法,属于对象

类方法不可以访问实例方法和实例变量,但是实例方法可以访问类方法和类变量 

访问类方法的方式:

  • 类名.类方法(推荐,高效,方便)
  • 对象.类方法(不推荐
     

代码演示: 

  • 对象
    public class Student3 {
        double score;   //分数
    
        public static void HelloWorld(){    //Static修饰的成员方法——类方法
            System.out.println("HelloWorld!");
        }
    
        public void Pass(){     //没用Static修饰的成员方法——实例方法
            System.out.println(this.score >= 60? "及格" : "不及格");
        }
    }
  • 访问
    public class StaticDemo3 {
        public static void main(String[] args) {
    
            //通过类名访问实例方法,推荐
            Student3.HelloWorld();
    
            //通过对象访问实例方法.不推荐
            Student3 s = new Student3();
            s.HelloWorld();
    
            //通过类名访问实例方法,报错
    //        Student3.Pass();
        }
    }

    注:同实例对象一样实例方法也不能通过类名去访问
     

小知识:

其实main方法就是一个类方法,当我们用java命令执行程序的时候,虚拟机会用当前类直接.main()方法,也就是说 java test == test.main(), 那么main方法括号里的字符串数组是干什么的呢?:,这个数组实际上是用来接收数据的,并且我们也可以去使用这个数组里的数据(如果有的话),我们可以在控制台执行class文件的时候传入一些参数给main方法使用,比如现在有这麽一串代码:

public class Test {
    public static void main(String[] args) {
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

在控制台编译执行并传入数据给它:

类方法的常见应用场景

  • 类方法最常见的应用场景是设计工具类

 工具类是什么

  • 用来完成某一个功能的,用来给开发人员共同使用的类方法

使用类方法设计工具类有什么好处 

  • 提高了代码复用,调用方便,提高了开发效率

        如果需要一个类只存一些需要重复使用的方法,那么就可以创造一个专门提供这些方法的工具类,在类里面创造需要的类方法,需要使用该方法的时候直接类名.类方法就可以很方便的使用了。例如有多个类都需要创建指定位数验证码时,就可以 创建一个工具类专门存放生成随机验证码方法以供调用:

        案例:

        假设现在有一个方法1需要创建一个四位验证码,另一个方法2需要创建一个六位验证码,为了提高代码复用,减少重复代码,我们就可以专门为创建验证码这个方法设计一个方法类,放在工具类中以供调用:

方法1代码:

public class Demo1 {
    //需要创建四位验证码
    public void CreateCode(){
        System.out.println(MyUtil.CreateCode(4));
    }
}

方法2代码:

public class Demo2 {
    //需要创建六位验证码
    public void CreateCode(){
        System.out.println(MyUtil.CreateCode(6));
    }
}

工具类代码:

import java.util.Random;

public class MyUtil {   //专门存放需要重复使用的方法的工具类
    public static String CreateCode(int digit) {   //验证码随机生成方法,作为类方法提高复用性
        Random r = new Random();
        String numbers = "1234567890abcdefghijklmnopqistuvwxyzABCDEFGHIJKLMNOPQISTUVWXYZ";  //字符池
        StringBuilder code = new StringBuilder();

        while(digit-- != 0){    //传入的形参控制位数
                code.append(numbers.charAt(r.nextInt(0, 63)));
        }

        return code.toString();
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        Demo1 d1 = new Demo1();
        Demo2 d2 = new Demo2();

        d1.CreateCode();
        d2.CreateCode();
    }
}

运行结果:

小知识:

  • 为什么工具类中的方法要用类方法不用实例方法?
  • 用实例方法当然也是可行的,但是作为实例方法必须使用对象调用,必须先创建类对象才能调用相关实例方法,而此时对象只是为了调用方法,浪费内存,不如直接使用类方法
  • 因为工具类只是为了提供类方法而存在,不需要创建对象,所以其实可以将工具类的构造方法私有:

        


使用类方法、实例方法时的几点注意事项

  • 类方法中可以直接访问类变量,不可以直接访问实例变量
  • 实例方法中既可以直接访问类成员,也可以直接访问实例成员
  • 实例方法中可以出现this关键字,类方法中不可以出现this关键字


Static修饰代码块 

代码块是什么

  • 代码块是类的五大成分之一(成员变量、构造器、方法、代码块、内部类)

代码块按有无Static修饰分俩种:

  • 静态代码块
    -->格式:static{ ... }
    -->特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次
    -->作用:完成类的初始化,例如:对类变量的初始化赋值
  • 实例代码块
    -->格式:{ ... }
    -->特点:每次创建对象时,执行实例代码块,并在构造器前执行
    -->作用:和构造器一样,都是用来完成对象的初始化,例如对示例变量进行初始化赋值

代码演示: 

静态代码块:

public class Block {
    static int age = 18;    //类变量

    static{ //静态代码块,只会在类加载时执行一次
        System.out.println("静态代码块被执行");
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        System.out.println(Block.age);  //访问Block类的类变量,会先加载Block类
        System.out.println(Block.age);  //访问三次
        System.out.println(Block.age);
    }
}

结果:

虽然访问了三次类变量,但是静态代码块只在第一次访问加载时执行了一次

实例代码块:

public class Block {
    String name;    //实例变量

    { //实例代码块,每次创建对象在构造器前执行一次
        System.out.println("实例代码块执行");
    }

    public Block() {
        System.out.println("无参构造器执行");
    }

    public Block(String name) {
        System.out.println("有参构造器执行");
    }
}

测试:

public class Test {
    public static void main(String[] args) {
       Block b1 = new Block();  //创建对象并调用无参构造器
       Block b2 = new Block("小明");  //创建对象并调用有参构造器
    }
}

        结果:

每次创建对象时,都会在调用构造器之前执行一次实例代码块
虽然实例代码块可以给示例变量赋初值,但是意义不大,因为实例代码块不能传参,所有赋初值的实例变量都是一个值,所以一般不会去使用实例代码块给实例变量赋初值,但是可以用实例代码块记录日志之类的,比如每次有人创建对象,就可以在实例代码块记录一下


Static应用:单例设计模式

设计模式是什么

  • 一个问题通常有n种解法,其中肯定有一种解法时最优的,这个最优的解法就是设计模式
  • 设计模式总共有23种,对应各种软件开发种会遇到的问题

单例设计模式 

  • 确保一个类只有一个对象
  • 把类的构造器私有
  • 定义一个类变量记住类的一个对象
  • 定义一个类方法返回对象

代码演示: 

单例设计模式设计一个类:

public class SingleCase {

    private static SingleCase s = new SingleCase(); //2、定义一个类变量记住一个类对象

    private SingleCase(){}  //1、私有类的构造器

    public static SingleCase getObject(){   //定义一个类方法返回类对象
        return s;
    }
}

测试:

public class Test {
    public static void main(String[] args) {
//       SingleCase s = new SingleCase();   无法再通过原来的方法创建该类对象

        SingleCase s1 = SingleCase.getObject();  //但是可以通过类方法调用类变量返回一个对象
        SingleCase s2 = SingleCase.getObject();  //因为类变量只会在类加载的时候创建一次,所以通过这种方法创建的类对象都是同一个

        System.out.println(s1);
        System.out.println(s2);
    }
}

运行结果:

俩个类对象的地址都是一样的,说明它们引用的是同一个对象

单例设计模式的应用

这是官方提供的Runtime类,可以看到它就是使用的单例设计模式来设计的

比如说我们常用到的任务管理器就是单例设计模式,不管启动多少次任务管理器,它都只会打开那一个任务管理器。在只需要一个对象即可解决问题时,就可以使用单例设计模式来设计,即可以避免内存浪费

小知识:

        单例设计模式不止一种:

        像刚才代码演示的单例设计模式只是其中一种,称为饿汉式单例设计模式,除此之外还有懒汉式单例模式、双检索等等.......

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1365289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Saprk SQL基础知识

一.Spark SQL基本介绍 1.什么是Spark SQL Spark SQL是Spark多种组件中其中一个,主要是用于处理大规模的[结构化数据] Spark SQL的特点: 1).融合性:既可以使用SQL语句,也可以编写代码,同时支持两者混合使用. 2).统一的数据访问:Spark SQL用统一的API对接不同的数据源 3).H…

vueRouter 配合 keep-alive 不生效的问题

文章目录 问题说明案例复现demo 结构问题复现和解决 其实这个不生效的问题根本也不算一个问题,犯的错和写错单词差不多,但是也是一时上头没发现,所以记录一下,如果遇到同样的问题,也希望可以帮助你早点看到这个哭笑不得…

WWDG---窗口看门狗

一.简介 窗口看门狗跟独立看门狗一样,也是一个递减计数器不断的往下递减计数,必须在一个窗口的上限值(用户定义)和下限值(0X40,固定不能变)之间喂狗不会复位,在上限值之前和下限值之…

etcd储存安装

目录 etcd介绍: etcd工作原理 选举 复制日志 安全性 etcd工作场景 服务发现 etcd基本术语 etcd安装(centos) 设置:etcd后台运行 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册…

【hcie-cloud】【18】华为云Stack灾备服务介绍【容灾解决方案介绍、灾备方案架构介绍、管理组件灾备方案介绍、高阶云服务容灾简介、缩略词】【下】

文章目录 灾备方案概述、备份解决方案介绍容灾解决方案介绍华为云容灾解决方案概览云容灾服务云硬盘高可用服务 (VHA)VHA组网结构VHA逻辑组网架构VHA管理组件介绍VHA服务实现原理云服务器高可用服务(CSHA)CSHA物理组网架构CSHA逻辑组网架构CSHA服务组件间…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第五天-Linux消息共享内存练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

2024--Django平台开发-Web框架和Django基础(二)---Mysql多版本共存(Mac系统)

MySQL多版本共存(Mac系统) 想要在Mac系统上同时安装【MySQL5.7 】【MySQL8.0】版本,需要进行如下的操作和配置。 想要同时安装两个版本可以采取如下方案: 方案1:【讲解】 MySQL57,用安装包进行安装。 MyS…

像专家一样使用TypeScript映射类型

掌握TypeScript的映射类型,了解TypeScript内置的实用类型是如何工作的。 您是否使用过Partial、Required、Readonly和Pick实用程序类型? 你知道他们内部是怎么运作的吗? 如果您想彻底掌握它们并创建自己的实用程序类型,那么不要错过本文所涵盖的内容。…

2、Excel:基础概念、表格结构与常见函数

数据来源:八月成交数据 数据初探 业务背景 数据来源行业:金融行业(根据应收利息和逾期金额字段来判断) 可以猜测: 业务主体:某互联网金融公司(类似支付宝)也业务模式:给…

leetcode动态规划问题总结 Python

目录 一、基础理论 二、例题 1. 青蛙跳台阶 2. 解密数字 3. 最长不含重复字符的子字符串 4. 连续子数组的最大和 5. 最长递增子序列 6. 最长回文字符串 7. 机器人路径条数 8. 礼物的最大价值 一、基础理论 动态规划其实是一种空间换时间的基于历史数据的递推算法&…

Java异常机制:从混乱到控制的错误管理艺术

👑专栏内容:Java⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停 目录 一、异常的体系结构1、异常的体系结构2、异常的分类 二、异常的处理1、异常的抛出2、异常的捕获2.1、异常声明throws2.2、try-c…

C#中List<T>底层原理剖析

C#中List底层原理剖析 1. 基础用法2. List的Capacity与Count:3.List的底层原理3.1. 构造3.2 Add()接口3.3 Remove()接口3.4 Inster()接口3.5 Clear()接口3.6 Contains()接口3.7 ToArray()接口3.8 Find()接口3.8 Sort()接口 4. 总结5. 参考 1. 基础用法 list.Max() …

2024龙年艺术字矢量Ai设计文件60套

2024新年将至,设计师们早已开始为龙年海报、推文的制作摩拳擦掌。该合集不仅内容丰富多样,作为矢量文件资源,也能够让设计者更为轻松地编辑与创作。 合集内另附200多张电脑壁纸。 文件总大小368MB 链接:https://pan.quark.cn/s/0caab4cf065…

Google Earth Engine谷歌地球引擎GEE批量计算一年中每个指定天数范围内遥感影像平均值的方法

本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,计算长时间序列遥感影像数据在多年中,在每一个指定天数的时间范围内的平均值的方法。 本文是谷歌地球引擎(Google Earth Engine,GEE&#x…

MySQL BufferPool精讲

缓存的重要性 我们知道,对于使用InnoDB作为存储引擎的表来说,不管是用于存储用户数据的索引(包括聚簇索引和二级索引),还是各种系统数据,都是以页的形式存放在表空间中的,而所谓的表空间只不过…

杰发科技AC7840——CAN通信简介(2)

1.时钟频率 2.位时间 3.采样点 4.消息缓冲区 和ST、NXP的邮箱类似,AutoChips用了缓冲区的概念。 5.接收缓冲区 屏蔽掉demo程序的发送,只看接收情况 在回调中接收数据 先判断是不是进了接收中断 接收数据的处理函数 所有buff数据放到Info buff的内容 BUF…

环境中碳循环

含碳的物质有CO2、CO、CH4、糖类、脂肪和蛋白质等,碳循环以CO2为中心,CO2被植物、藻类利用进行光合作用,合成植物性碳;动物摄食植物就将植物性碳转化为动物性碳;动物和人呼吸放出CO2,有机碳化合物被厌氧微生…

AArch64 memory management学习(一)

提示 该博客主要为个人学习,通过阅读官网手册整理而来(个人觉得阅读官网的英文文档非常有助于理解各个IP特性)。若有不对之处请参考参考文档,以官网参考文档为准。AArch64 memory management学习一共分为两章,这是第一…

Github 2024-01-08开源项目周报 Top14

根据Github Trendings的统计,本周(2024-01-08统计)共有14个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5TypeScript项目3C项目2Dart项目1QML项目1Go项目1Shell项目1Rust项目1JavaScript项目1C#项目1 免费…

【网络安全】PKI加密

1、PKI概述 名称:Public Key Infrastruction 公钥基础设施 作用:通过加密技术和数字签名保证信息的安全 组成:公钥机密技术、数字证书、CA、RA 2、信息安全三要素 机密性 完整性 身份验证/操作的不可否认性 3、哪些IT领域用到PKI&…