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

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(); //定义学生对象1Student s2 = new Student(); //定义学生对象2Student.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.rhkb.cn/news/236832.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CCF模拟题 202309-2 坐标变换(其二)

问题描述 试题编号: 202309-2 试题名称: 坐标变换(其二) 时间限制: 1.0s 内存限制: 512.0MB 问题描述: 对于平面直角坐标系上的坐标 (x,y),小 P 定义了如下两…

Web开发:SQLsugar的安装和使用

一、安装 第一步,在你的项目中找到解决方案,右键-管理解决方案的Nuget 第二步,下载对应的包,注意你的框架是哪个就下载哪个的包,一个项目安装一次包即可 点击应用和确定 安装好后会显示sqlsugar的包 二、使用&#xf…

【前端转安卓】-Java基础知识笔记

常量定义:final public class HelloWorld {// 静态常量public static final double PI 3.14;// 声明成员常量final int y 10;public static void main(String[] args) {// 声明局部常量final double x 3.3;} }变量声明、赋值 String username,address,phone,te…

C++力扣题目513找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 思路 本题要找出树的最后一行的最左边的值。此时大家应该想…

odoo17 | Qweb模板简介

前言 到目前为止&#xff0c;我们的房地产模块的界面设计还相当有限。构建列表视图很简单&#xff0c;因为只需要字段列表。表单视图也是如此&#xff1a;尽管使用了几个标签&#xff0c;如 <group>标签或 <page>标签 &#xff0c;但在设计方面几乎没什么可做的。…

开通微信商家转账到零钱怎么做?场景模板

商家转账到零钱是什么&#xff1f; 商家转账到零钱功能是指商家可以通过支付平台将资金直接转账到用户的零钱账户中。在这种情况下&#xff0c;商家不需要用户提供银行账户信息&#xff0c;而是使用支付平台的转账功能将资金直接转移到用户的零钱账户中。 商家转账到零钱的使…

【前后端的那些事】treeSelect树形结构数据展示

文章目录 tree-selector1. 新增表单组件2. 在父组件中引用3. 父组件添加新增按钮4. 树形组件4.1 前端代码4.2 后端代码 前言&#xff1a;最近写项目&#xff0c;发现了一些很有意思的功能&#xff0c;想写文章&#xff0c;录视频把这些内容记录下。但这些功能太零碎&#xff0c…

紫光展锐5G扬帆出海 | Blade系列勇当拉美5G先锋

5G对拉丁美洲&#xff08;简称“拉美”&#xff09;绝大多数消费者来说还是一个新鲜技术。GSMA报告显示&#xff0c;过去五年&#xff0c;拉美运营商在移动网络方面的资本开支大部分用于部署4G网络。但在5G网络方面拉美也在积极大力投入中&#xff0c;紧跟全球5G发展大潮&#…

企业微信forMAC,如何左右翻动预览图片

1、control commandshifd 进入企业微信的debug调试模式 2、按照如下步骤选择 3、重启企业微信

【TC3xx芯片】TC3xx芯片电源管理系统PMS详解

目录 前言 正文 1.供电模式选择&#xff08;Supply Mode Selection&#xff09; 1.1 供电域 1.2 供电模式 1.3 供电阈值 1.4 供电上升和下降行为Supply Ramp-up and Ramp-down Behavior 1.5 EVRC产生供电 2. 电源监控 2.1 电源监控原理 2.2 Primary低电压监控 2.3 …

前端面试题集合五(css)

CSS 面试知识点总结 本部分主要是笔者在复习 CSS 相关知识和一些相关面试题时所做的笔记&#xff0c;如果出现错误&#xff0c;希望大家指出&#xff01; 目录 1.介绍一下标准的 CSS 的盒子模型&#xff1f;低版本 IE 的盒子模型有什么不同的&#xff1f;2.CSS 选择符有哪些…

本地静态资源打包出来,本地配置ng访问服务器(uniapp打包成h5后,使用打包资源连接测试环境测试)

1.下载ng https://nginx.org/en/download.html 2.解压下载的压缩包 3.打包h5静态资源 4.将打包出来的资源放入ng -》html文件夹下面 5.进入ng-》conf-》nginx.conf 进行转发配置 6.启动ng服务&#xff0c;点击nginx.exe 7.浏览器直接访问http://localhost:8081/#/&#x…

C++内存管理机制(侯捷)笔记3

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 第三讲&#xff1a;malloc和…

C++进阶--AVL树

AVL树 一、AVL树的概念二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转4.1 左单旋4.2 右单旋4.3 左右双旋4.4 右左双旋 五、AVL树的验证六、AVL树的删除七、AVL树的性能 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退…

分裂联邦学习论文-混合联邦分裂学习GAN驱动的预测性多目标优化

论文标题&#xff1a;《Predictive GAN-Powered Multi-Objective Optimization for Hybrid Federated Split Learning》 期刊&#xff1a;IEEE Transactions on Communications, 2023 一、论文介绍 背景&#xff1a;联邦学习作为一种多设备协同训练的边缘智能算法&#xff0…

D25XB100-ASEMI家用电器整流桥D25XB100

编辑&#xff1a;ll D25XB100-ASEMI家用电器整流桥D25XB100 型号&#xff1a;D25XB100 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-5&#xff08;带康铜丝&#xff09; 平均正向整流电流&#xff08;Id&#xff09;&#xff1a;25A 最大反向击穿电压&#xff08;VRM&…

最好的 8 个解锁 Android 手机的应用程序分析

如何解锁我的 Android 手机是一个困扰全球数百万人的问题。有多种Android解锁器可用于解锁手机。用户应确保选择最好的应用程序以轻松满意地完成工作。必须注意的是&#xff0c;数据在解锁手机的整个过程中都是安全可靠的。此类应用程序还应该能够在所有情况下检索数据。 锁屏移…

【STM32】STM32学习笔记-串口发送和接收(27)

00. 目录 文章目录 00. 目录01. 串口简介02. 串口相关API2.1 USART_Init2.2 USART_InitTypeDef2.3 USART_Cmd2.4 USART_SendData2.5 USART_ReceiveData 03. 串口发送接线图04. USB转串口模块05. 串口发送程序示例06. 串口发送支持printf07. 串口发送支持printf_v208. 串口发送和…

Transformer - Attention is all you need 论文阅读

虽然是跑路来NLP&#xff0c;但是还是立flag说要做个project&#xff0c;结果kaggle上的入门project给的例子用的是BERT&#xff0c;还提到这一方法属于transformer&#xff0c;所以大概率读完这一篇之后&#xff0c;会再看BERT的论文这个样子。 在李宏毅的NLP课程中多次提到了…

【MySQL】:掌握SQL中DDL的数据库定义与操作

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; MySQL从入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. SQL的分类二. DDL数据库操作2.1 查询所有数据库2.2 查询当前数据库2.3 创建数…