深入了解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.mzph.cn/news/605392.shtml

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

相关文章

ssm基于Vue.js的网上招聘系统设计与实现+vue论文

摘 要 计算机网络发展到现在已经好几十年了,在理论上面已经有了很丰富的基础,并且在现实生活中也到处都在使用,可以说,经过几十年的发展,互联网技术已经把地域信息的隔阂给消除了,让整个世界都可以即时通话…

小结:利用PostMessage实现Web中的跨文档通信

本周开发项目时,做了一个技术小结,帮助快速理解 & 使用 PostMessage。 PostMessage是通信API,它允许不同窗口之间进行跨文档通信,包括同源和跨源的通信。 基本使用方法 使用PostMessage非常简单,主要包括两个步…

Qt6入门教程 4:Qt Creator常用技巧

在上一篇Qt6入门教程 3:创建Hello World项目中,通过创建一个Qt项目,对Qt Creator已经有了比较直观的认识,本文将介绍它的一些常用技巧。 Qt Creator启动后默认显示欢迎页面 创建项目已经用过了,打开项目也很简单&#…

漫漫数学之旅002

文章目录 一、经典格言二、数学习题三、古今评注四、科学家小传 - 开普勒开普勒第一定律(椭圆轨道定律)开普勒第二定律(面积定律)开普勒第三定律(调和定律)一、经典格言 自然追求尽可能的简单。——约翰尼斯开普勒(Johannes Kepler) 二、数学习题 假定你只有容量为3夸…

【HDFS】一次备NameNode宕机过久导致的生产事故

一次备NameNode宕机过久导致的生产事故 故障描述 最近发生的一个临时故障,情况是一个启了HA的HDFS集群,在2023年9月份因为两台NameNode同时启动产生一些问题,所以当时将一台节点停止,一直没有启动,具体为什么当时有问…

跟一个学霸应该聊些什么?

与学霸聊天时,可以考虑以下几个方面: 学术兴趣和研究:询问他们的学术领域、研究项目,或者最近读到的有趣论文。这可以激发深入的学术讨论。 最新科学发现:谈论最新的科学和技术进展,尤其是与他们专业相关的…

高效的图纸管理技巧、高效的图纸管理软件

高效的图纸管理技巧包括以下几个方面: 分类和组织:首先,确保你有一种清晰的图纸分类和组织系统。创建不同的文件夹来储存不同类型的图纸,如建筑、机械、电气等。更细的分类还可以按项目或客户进行划分。命名规则:为图…

Java默认只有一个线程

Java默认只有一个线程 在Java中,默认情况下只有一个线程运行。这意味着在一个Java程序中,只有一个主线程可以执行代码。但是,有时我们也会说Java默认有两个线程,一个主线程负责执行代码和一个GC线程负责(垃圾回收&…

QT:单例

单例的定义 官方定义:单例是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。 单例的写法 抓住3点: 构造函数私有化(确保只有一个实例)提供一个可以获取构造实例的接口(提供唯一的实…

03.分支结构

分支结构 应用场景 迄今为止,我们写的Python代码都是一条一条语句顺序执行,这种代码结构通常称之为顺序结构。然而仅有顺序结构并不能解决所有的问题,比如我们设计一个游戏,游戏第一关的通关条件是玩家获得1000分,那…

实现珠宝业务快速扩张的关键:广东省珠宝行业ERP系统的价值

珠三角地区具备毗邻港澳及改革开放先行地的优势,为当地的产业发展带来技术和资金;同时,改革开放后该地区经济发展较快,当地居民的消费水平提高,消费转型,对珠宝首饰产品的需求也相应提高,逐渐形…

1080p 1k 2k 4k 8k 分辨率,2K就不应该存在。

众所周知 1K(1080P):分辨率为19201080像素,2K:分辨率为25601440像素4K:分辨率为38402160像素8K:分辨率为76804320像素 边长比例,和像素比例如下: 2K宽高都是1k的1.333…

docker run 命令详解

一、前言 Docker容器是一个开源的应用容器引擎,让开发者可以以统一的方式打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何安装了Docker引擎的服务器上(包括流行的Linux机器、Windows机器),也可以实现虚拟…

数据聚合、自动补全、数据同步、es集群

目录 数据聚合 聚合的分类 DSL实现bucket聚合 DSL实现Metrics聚合 RestAPI实现聚合 多条件聚合 带过滤条件的聚合 自动补全 安装拼音分词器 自定义分词器 completion suggester查询 修改索引库数据结构 RestAPI实现自动补全查询 实现搜索框自动补全 数据同步 数…

华为OD机试会遇到原题吗?

答案是:会遇到。 OD机试是有题库的,每半年刷新一次题库,题库题目在100-200到题之间,2024年考的是统一考试C卷,题库我基本已经收集全了。 学生们反馈,最近的考试基本会遇到2-3道原题,高分比较简…

【2024系统架构设计】 系统架构设计师第二版-层次式架构设计理论与实践

目录 一 表现层框架设计 二 中间层架构设计 三 数据访问层设计 四

RabbitMQ(九)死信队列

目录 一、简介1.1 定义1.2 何时进入死信队列?1.3 死信消息的变化1.4 死信队列的应用场景1.5 死信消息的生命周期 二、代码实现2.1 死信队列的配置步骤2.2 配置类2.3 配置文件2.4 生产者2.5 业务消费者2.6 死信消费者2.7 测试结果 三、总结 RabbitMQ 是流行的开源消息…

MySQL数据库进阶-索引

索引 索引是帮助 MySQL 高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级…

【Spring Boot 3】【数据源】自定义JDBC数据源

【Spring Boot 3】【数据源】自定义JDBC数据源 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总…

CSS3渐变属性详解

渐变属性 线性渐变 概念:线性渐变,指的是在一条直线上进行的渐变。在线性渐变过程中,起始颜色会沿着一条直线按顺序过渡到结束颜色 语法: background:linear-gradient(渐变角度,开始颜色,结束颜色);渐变…