Java中static关键字和代码块的学习

news2024/9/27 21:25:57

本文介绍了Java中static关键字的使用,即静态成员变量和成员方法以及使用,静态与非静态成员变量和方法的对比总结
Java中的代码块介绍与最后结合代码块和构造方法后的初始化代码执行顺序的练习

static和代码块的学习

  • 三.认识static关键字
    • 1.static修饰成员变量
    • 2.static修饰成员方法
    • 3.静态成员变量初始化的方法
    • 4.静态与非静态的简单对比总结
      • ①.静态成员变量和非静态成员变量
      • ②.静态成员方法与非静态成员方法
  • 四.Java中的代码块
    • 1.普通代码块
    • 2.构造代码块
    • 3.静态代码块
    • 4.分析初始化代码的运行顺序

三.认识static关键字

static关键字也就是静态的意思,在java中可以修饰成员变量,成员方法,代码块…

1.static修饰成员变量

static修饰的成员变量,称为静态成员变量或类成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。

[权限修饰符] static 数据类型 变量名 = [就地初始化值];

示例:

public class Student{
public static String school1="清华大学"; //直接就地初始化 在加载类时申请空间后会直接赋值
//static修饰 成员变量为静态成员变量(类变量)存放在方法区 是加载类时候就申请了空间 不属于对象 是属于类的 也就是所有通过类实例化对象共用的一个变量
}

此时定义的school1 为这个类里的静态成员变量,是属于类的,通过这个类实例化的所有对象都共享这一个变量.

访问静态成员变量的方法:

 System.out.println(Student.school1);  
 //被static修饰的成员变量属于类变量 直接通过类名.变量 访问 最推荐这种
   System.out.println(student1.school1); 
  // 也可以通过student1访问school 不推荐 引用变量也属于Student类型也可以访问类变量
   Student student2=null;
 System.out.println(student2.school1);
  //可以看出 student2引用变量里是null表示没有指向任何对象 但是可以输出清华大学,student2不指向对象不妨碍其访问类对应的类变量
  System.out.println(((Student)null).school1);
  //甚至可以把null空引用强转为Student类 此时可以访问Student类里的成员变量

在这里插入图片描述

【静态成员变量特性】

  1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
  2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
  3. 静态成员变量存储在方法区当中
  4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)

2.static修饰成员方法

一般设置的静态成员变量也会被封装设置为private权限,而此时需要对外提供公开接口也就是public权限的静态成员方法,
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。

定义静态成员变量:
[权限修饰符] static 返回值 方法名(形参列表…){方法体}

public static void func(){
//...
}

这也就是刚开始学习方法时写的静态方法,学习static后,方法可以分为静态方法非静态方法

静态方法的访问:

Student.study(); //类名 访问类方法   最推荐这种
student1.study();  // 引用变量访问类方法 不推荐
 ((Student)null).study();  //将null强转为对应类类型 访问类方法 只要是类类型的就可以访问此类里的成员方法或成员变量 不推荐
new Student("张三",18).study();  //可以直接实例化对象得到对象地址后直接调用 类方法或者变量 因为对象地址也属于类类型
Note.test();  // 可以通过当前类名访问其类成员方法
 test();   // 是在当前类里面调用里面的静态方法 可以直接写方法名调用不用加类名 在调用其他类里的静态方法需要在前面加上类名

在这里插入图片描述

【静态方法特性】

  1. 不属于某个具体的对象,是类方法
  2. 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
  3. 不能在静态方法中访问任何非静态成员变量

3.静态成员变量初始化的方法

静态成员初始化可以通过
1.就地初始化(在定义时右边同时给其赋值)
2.通过静态代码块初始化(涉及到下面的代码块学习)
3.通过调用静态成员方法初始化(set get静态方法)
4.通过构造方法(需要实例化对象后才能进行初始化 不推荐,多此一举)
5.通过非静态成员方法初始化(需要实例化对象又要调用对应的成员方法 不推荐.)

注意:

静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性

4.静态与非静态的简单对比总结

在接触学习static后,在类里的定义就有了静态和非静态之分,它们之间有这很大的不同

①.静态成员变量和非静态成员变量

静态成员变量前面有static修饰 表示类成员,其不属于对象,在类加载时就会在方法区被创建一份空间
不管实例化多少个对象,静态成员变量开辟的空间只有一个(所有对象共享一个)

非静态成员变量前面没有static 是对象成员,属于对象,在实例化对象后会为其在堆区申请开辟一份空间
每实例化一个对象 就会多一份对应的成员变量空间(每个对象都有一份)

静态成员变量通过类访问
非静态成员变量通过对象引用访问

当我们使用一个类时,其一个属性是所有对象共享时,不需要每new一个对象都给其一个空间时就设置静态成员变量,这样设计也能节省空间的开辟.
如: 假设一个班级里的学生,每个学生都是属于这个班级,那么学生类里 班级属性就可以设置为静态的,这样每个学生对象都共用那一个静态成员变量,不用额外再为自己开一个记录班级属性的变量

②.静态成员方法与非静态成员方法

在学习static后,除构造方法外,一个类里可以有静态方法也有非静态方法,其存放在方法区.

1.静态成员方法一般用于给静态成员变量初始化,

为了体现封装性,静态成员变量会被设置为private,此时可以通过静态成员方法作为外部接口给静态成员变量初始化赋值

2.在静态成员方法内不能直接访问非静态成员变量或者成员方法

因为在静态成员方法是可以直接被类名. 调用的,而此时并没有实例化对象 或者可能实例化了多个对象,而此时编译器根本不知道对应的是哪个对象的成员变量和成员方法
也就是静态成员方法内不会存在 this引用,即根本无法对对象进行操作,除非手动传对象地址或者在内部实例化对象操作才能对对象进行访问

3.非静态成员方法内可以访问静态成员方法或者静态成员变量,也可以访问非静态成员变量和非静态成员方法

因为非静态成员方法如果被调用,说明一定实例化了对象,此时可以在成员方法内访问成员变量和其他成员方法,也可以直接访问类成员变量和成员方法

虽然非静态成员方法在方法区也只有一份,但是其内部隐藏了this引用,即不管有多少个对象,每个对象调用这个非静态方法,该方法在执行时会有一个this引用存放当前对象的地址,以便区分不同的对象,对不同对象内的成员进行操作

4.静态成员方法 通过类来访问

在加载时此方法就会存到方法区,可以直接类名访问,如果在当前类里访问可以直接用方法名即可访问

5.非静态成员方法 需要实例化对象后,通过对象引用访问

非静态成员方法被不同对象引用调用其内部this引用可以表示不同对象的地址,以此来表示不同的对象行为,因此可以对指定对象成员进行操作

非静态成员成员方法比静态成员方法内部多了this引用,当需要访问不同对象内的成员时,可以设置为非静态成员方法 表示对象行为 可以更方便调用类里的静态或非静态成员
而静态不具备this引用,不能直接调用非静态的,
还需要在方法内实例化对象或者用形参接受对象引用,
静态成员方法一般用于给静态成员变量初始化,也可以用于一般做算法,刷题等不需要依赖对象使用,此时可以快速调用方法不需要实例化等多余操作

四.Java中的代码块

使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:

普通代码块 构造块 静态块 同步代码块(涉及多线程)

1.普通代码块

普通代码块为定义在方法内部的代码块

public class Main{
public static void main(String[] args) {
//int x;  此处编译错误 在普通代码块内有 x  在其外部上方不能存在同名的变量
{ //直接使用{}定义,普通方法块  不受任何if等限制的 一步步往下执行
int x = 10 ;  //在普通代码块里的 x为10
System.out.println("x1 = " +x);
} 
//结束普通代码块后 x生命周期 作用域都结束!
int x = 100 ;  //在普通代码块外的x 为100
System.out.println("x2 = " +x);
 }
} // 执行结果
x1 = 10
x2 = 100

该代码块用于表示方法内一段局部空间里 进行某些运算.在出这段代码块局部空间后,代码块里面的局部变量作用域生命周期都会结束,下面非普通代码块的区域能用代码块内同名的变量且不会受影响
但是在普通代码块上方不能定义和普通代码块内相同名字的变量

2.构造代码块

构造代码块又称非静态代码块或者实例化代码块:定义在类内部,方法外部


class Person{
  int age =1;  //成员变量 就地初始化赋值为1

   { //定义的类内部 方法外部 
        int age; // 代码块内定义的变量为局部变量 可以和全局变量同名
        this.age=2; // 通过this 引用 访问成员

        System.out.println("非静态代码块/实例化代码块/构造代码块");
        //定义在类里面方法外面的代码块  和构造方法一样一般 用来初始化成员变量的
        //在顺序上和就地初始化成员变量一样 会在编译时放在构造方法前面 具体谁在前面看定义代码所处的先后顺序
        System.out.println(this.age); // 此时就地初始化在前 构造代码块在后
        //构造方法块内的变量是局部变量
 }
}

构造代码块在创建对象的时候执行一次,每创建一个对象都会为其对应的对象执行一次构造代码块
构造代码块一般用于给成员变量进行初始化
在构造代码块内定义的变量是局部变量且可以出现和成员变量同名的局部变量,需要通过this引用访问成员变量
定义的成员变量可以放在构造代码块的前后,如果定义的成员变量有就地初始化语句时 会根据二者定义的位置按先后顺序执行,但是都会在构造方法前执行

3.静态代码块

静态代码块:定义在类内部,方法外部,被static关键字修饰的代码块


class Person{
 static school2="1";
 static{

        school2="6";
        System.out.println(school2);
        System.out.println("静态代码块");//一般用于给静态成员变量初始化

        //类里面方法外面且被static修饰的代码块 在类加载的时候会执行的代码块,只执行一次 有多个代码块时按先后顺序执行
        //当声明静态成员变量在静态代码块后面时 静态代码块内部可以对静态成员变量进行赋值初始化但是不能打印访问!
        // 在静态代码当静态代码块里有对静态成员变量n的打印访问 此时声明静态成员变量n的语句必须在该静态代码块前面 否则会发生非法向前引用
        //静态代码块中的变量是局部变量!!

    }
    //static student2="4"  定义在静态代码块下面 在代码块内打印会发生非法向前引用
}

静态代码块只在类被加载的时候执行一次,实例化对象并不会执行静态代码块,即整个类生命周期只被执行一次
一般用于初始化静态成员变量
静态代码块不能初始化非静态成员变量因为其加载的时候并没有对象(内部不存在this),但是构造代码块可以给静态成员变量赋值(内可以使用this)
当要初始化的静态成员变量有就地初始化时根据其和静态代码块的先后顺序决定哪个先执行

当要初始化的静态成员变量定义在静态成员变量下方时,此时可以给其初始化,但是如果要打印访问时会弹出非法访问错误!

在这里插入图片描述

4.分析初始化代码的运行顺序

以下是使用分别有静态和非静态成员变量和对应的就地初始化 以及静态非静态代码块 和构造方法 ,当实例化一个成员对象后,分析一下按什么顺序执行初始化语句

class Student{

    private int age=1;  //1

      //static修饰 成员变量为静态成员变量(类变量)存放在方法区 是加载类时候就申请了空间 不属于对象 是属于类的 也就是所有通过类实例化对象共用的一个变量
    private static String school2="1";//2

   public Student(){ //3
        System.out.println("无参构造方法");

    }

    {

        int age;
        this.age=2;

        System.out.println("非静态代码块/实例化代码块/构造代码块"); //4

        System.out.println(this.age); // 此时就地初始化在前 构造代码块在后

    }
    static{ // 就地初始化在前 代码块在后

        school2="6";
        System.out.println(school2);
        System.out.println("静态代码块");//5


    }


}
public class Note {
public static void main(String[] args) {
        Student student=new Student();// 实例化Student对象后初始化的代码执行顺序是什么?
    }
}

在这里插入图片描述

初始化执行顺序为: 2 5 1 4 3

下面简单分析执行顺序:

在实例化Student对象前先加载Student类 ,加载类时 先为静态成员变量开辟空间,然后根据就地初始化和静态代码块先后顺序谁在前先执行谁
再实例化Student对象,给成员变量开辟空间,再按就地初始化和构造代码块先后顺序执行,最后再执行构造方法!

在这里插入图片描述

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

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

相关文章

GAMES101-计算机图形学入门 LEC4: TRANSFORMATION-3D

本节课程视频地址:https://www.bilibili.com/video/BV1X7411F744/?p4 补充上一节课的一个内容,旋转矩阵的逆矩阵是它的转置,也就是说有R−θRθ−1RθTR_{-\theta} R_\theta^{-1}R_\theta^TR−θ​Rθ−1​RθT​ 上节课讲了,…

【go】结合一个go开源项目分析谷歌浏览器cookie为什么不安全 附go项目导包失败怎么解决教程

本文创作背景 源于谷歌浏览器提示密码被泄露 并且某站很快收到了异地企图登录的提醒。 当即怀疑是不是谷歌浏览器保存的密码不安全,最后查阅诸多资料 并找到一个go语言编写的开源项目进行研究,虽然最终不能确定密码是如何泄露的 但研究结论还是让人不由感…

在华为MateBook Ego的arm windows 11上安装hyper-V虚拟机

入手一台华为matebook Ego的笔记本,由于想要测试一些arm的驱动功能,经常会把系统搞蓝屏,于是想安装一个虚拟机,于是试了vmware ,visual-box,由于本机是arm架构上面两个软件都无法进行正常安装,可能是由于有…

Excel+SQL实战项目 - 餐饮业日销售情况分析仪

目录1、要完成的任务2、认识数据3、SQL数据加工4、excel形成分析仪1、要完成的任务 目标:结合SQL和excel实现餐饮业日销售情况分析仪,如下表: 认识分析仪: 切片器:店面 分为四部分:KPI 、组合图、饼图、数…

如何自学芯片设计?

众所周知,芯片设计自学还是比较困难的,更不存在速成的。这里简单说一下学习的规划。 学会相应的知识 无论是科班毕业,还是理工科专业,想要入行IC,那就一定要具备相关的基础知识。尤其是在学校里,学习的很…

Centos7 内核升级

一、背景 在 CentOS 使用过程中,高版本的应用环境可能需要更高版本的内核才能支持,所以难免需要升级内核,所以下面将介绍yum和rpm两种升级内核方式。 关于内核种类: kernel-ml——kernel-ml 中的ml是英文【 mainline stable 】的缩写&…

2W字正则表达式基础知识总结,这一篇就够了!!(含前端常用案例,建议收藏)

正则表达式 (Regular Expression,简称 RE 或 regexp ) 是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")正则表达式使用单个字符串来描述、匹配一系列匹…

wpscan常见的使用方法

目录 简单介绍 暴力破解 信息收集 指定用户爆破 命令集合 简单介绍 Wordpress是一个以PHP和MySQL为平台的免费自由开源的博客软件和内容管理系统。 WPScan是Kali Linux默认自带的一款漏洞扫描工具,它采用Ruby编写,能够扫描WordPress网站中的多种安…

微信微店怎么开店铺步骤【微信开店】

商家在微信平台主要是通过什么方式进行卖货呢,大家的答案都会是微信小店、小程序微店铺之类的,的确微信店铺是商家在微信平台上重要的卖货渠道,那么微信微店怎么开店铺,下面就给大家分享微信微店怎么开店铺步骤。 一、准备好资料…

Netty启动流程源码剖析

案例 本文利用natty-all-source 包下的的demo案例 echo来分析下源码,代码如下:server 端代码 /*** Echoes back any received data from a client.*/ public final class EchoServer {static final boolean SSL System.getProperty("ssl") …

day14_oop_抽象_接口

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、抽象 三、接口 零、 复习昨日 多态的好处: 扩展性强.加入新的功能,不需要改动代码降低代码耦合度(解耦合或者松耦合) 一、抽象类 1.1 抽象类…

C# VS2010 Winform 学习笔记遇见问题

参考书本《Visual C# .Net程序设计与应用开发》 学习C#: 对象的封装性:通过get()、set()函数读写。 1.Visual C#面向对象编程中的继承、多态。 2.enum:枚举,array.copy方法:数组拷贝,public static voi…

以应用为导向,看声纹识别中的音频伪造问题

声纹识别,又称说话人识别,是根据语音信号中的声纹特征来识别话者身份的过程,也是一种重要的生物认证手段。历经几十年的研究,当前声纹识别系统已取得了令人满意的性能表现,并在安防、司法、金融、家居等诸多领域中完成…

jenkins构建报错:.java:16: error: package javafx.util does not exist

1、报错 jenkins构建报错 package javafx.util does not exist2、报错原因 代码发现使用了javafx类,该类仅存在OracleJDK中,OpenJDK中没有该类。 jenkins服务器安装的是openjdk 3、卸载OpenJDK 具体不概述了 4、离线安装OracleJDK 1)…

SPI规范的使用和简介

前言 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。 整体机制图如下: Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的…

win11/10+opencv3.x/4.x配置 VS2019方法(简单使用,亲测)

首先下载 opencv,去官网下载百度》输入opencv,点击opencv|home,进入官网。点击 “Library”---->Release点击 对应版本下的 window版本,点击 --安装--extract---》设置路径。这个就是把库文件扩展到指定的路径下,扩…

Nacos集群+Nginx负载均衡

搭建Nacos集群 注意: 3个或3个以上Nacos节点才能构成集群。要求服务器内存分配最好大于6G以上(如果不够则需修改nacos启动脚本中的默认内存配置)根据nacos自带的mysql建库脚本建立对应数据库(/conf/nacos-mysql.sql)如果是三台服…

KNN&K-means从入门到实战

作者:王同学 来源:投稿 编辑:学姐 1. 基本概念 1.1 KNN k近邻法(k-nearest neighbor,k-NN)是一种基本分类与回归方法。 k近邻法的输入为实例的特征向量对应于特征空间的点;输出为实例的类别&…

发布新闻的步骤和技巧

发布新闻是一项非常重要的任务,无论是企业还是个人,都可以通过发布新闻来传达信息和宣传自己。以下是发布新闻的步骤和技巧,帮助你成功发布一条新闻。1、确定新闻的目标受众在发布新闻之前,你需要确定新闻的目标受众。你希望这条新…

多元回归分析 | CNN-GRU卷积门控循环单元多输入单输出预测(Matlab完整程序)

多元回归分析 | CNN-GRU卷积门控循环单元多输入单输出预测(Matlab完整程序) 目录 多元回归分析 | CNN-GRU卷积门控循环单元多输入单输出预测(Matlab完整程序)预测结果评价指标基本介绍程序设计参考资料预测结果 评价指标 训练结束: 已完成最大轮数。 训练集平均绝对误差MAE…