java中的static关键字

码林褶皱
• 阅读 135

java中的static关键字

  1. 概述

假设有一个学生类,它的数据成员有姓名、年龄、学号、教室,对于在同一个班的同学来讲,每个同学的姓名、年龄、学号或许都是不一样的,但是教室肯定是一样的,如果有40个同学,我有必要把40个同学的教室名都设置一遍吗?没必要,教室名是40个同学共享的一个属性,它不同于名字、学号这些,当我们给教室这个变量前面加上static后,它就是一个共享的属性了,我们只需把共享的属性设置一遍,所有的对象就会共享到这一设置。

public class Student{
    private String name;  //名字
    private int age;      //年龄
    private int ID;       //学号
    private static String Room; //加上static关键字,变成共享的一个属性
}

  1. 静态static关键字修饰成员时

如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于这个类。多个对象共享同一份数据

2.1 用代码演示一遍
先创建一个学生类
public class Student {
        //姓名
        private String name;
        
        //年龄
        private int age;
        
        //学号
        private int ID;
        
        //教室,我没加private关键字,是想可以直接通过Student类来修改它
        static String room;

        //生成无参构造和有参构造
        public Student() {
        }

        public Student(String name, int age, int iD) {
                this.name = name;
                this.age = age;
                this.ID = iD;
        }

        //生成各成员的setter和getter
        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }
        
        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

        public int getID() {
                return ID;
        }

        public void setID(int iD) {
                ID = iD;
        }

    public static String getRoom() {
                return room;
        }

        public static void setRoom(String room) {
                Student.room = room;
        }
}

在main中创建对象,并打印个人信息
public class staticField {

        public static void main(String[] args) {
                //先设置一下大家的教室,我们说静态成员是属于类的,所以可以直接通过(类名称.成员变量)设置教室
                Student.room = "通信1班";
                
                //新建一个学生对象小明,20岁,学号1号
                Student one = new Student("小明", 20, 1);
                
                //再新建一个学生对象小红,21岁,学号2号
                Student two = new Student("小红", 21, 2);
                
                //将小明和小红的个人信息打印一遍,顺便看看他们的教室是不是都一样
                System.out.println("学生名字:" + one.getName() + "," + "年龄:" + one.getAge() + ","  + "学号:" + one.getID() + "," + "教室:" + Student.room);
                
                System.out.println("学生名字:" + two.getName() + "," + "年龄:" + two.getAge() + "," + "学号:" + two.getID() + "," + "教室:" + Student.room);
        
            
        //在这里,我们当然也可以通过对象的方法来修改教室
        //但是,以对象的方式修改,在eclipse会有警告:类型Student中的静态方法应该以静态方式访问
        one.setRoom("通信2班");
                System.out.println(one.getRoom());
    }
}

/*输出结果:
    学生名字:小明,年龄:20,学号:1,教室:通信1班
    学生名字:小红,年龄:21,学号:2,教室:通信1班
    通信2班
*/

  1. static关键字修饰方法成员时

一旦使用static修饰成员方法,那么就成为了静态方法。静态方法不属于对象,而是属于类

如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它

3.1 static修饰方法(代码演示)
先创建一个MyClass类,然后在里面添加一个静态方法和非静态方法
public class MyClass {
    public void method(){
        System.out.println("这是一个普通成员方法");
    }

    public static void methodStatic(){
        System.out.println("这是一个静态成员方法");
    }
}

在main中进行调用
public class staticMain {
    public static void main(String[] args) {
        //首先创建对象
        MyClass obj = new MyClass();
        //然后才能使用没有static关键字的内容
        obj.method();

        //对于静态方法来说,可以通过对象名来进行调用,也可以直接通过类名称来调用
        obj.methodStatic();  //正确,不推荐,会让人误以为它是一个普通的成员方法,这种写法在编译之                                                          后而会被javac翻译成(类名称.方法)
        MyClass.methodStatic(); //正确,推荐,既然它是静态的方法,就用它特有的(类名称.方法)来                                                                进行调用

        //对于本类当中的静态方法,可以省略类名称,当然也可以不省
        myMethod();    //在编译时,也会被翻译成staticMain.myMethod();
        staticMain.myMethod();  //与上面的写法,完全等效
    }

    public static void myMethod(){
        System.out.println("本类当中的静态方法");
    }
}

/*输出结果:
    这是一个普通成员方法
    这是一个静态成员方法
    这是一个静态成员方法
    本类当中的静态方法
    本类当中的静态方法
*/

小总结
无论是静态成员变量,还是静态成员方法,如果有了static,都推荐使用类名称来进行调用,格式如下:
静态变量:类名称.变量名
静态方法:类名称.方法名
3.2 注意事项
第一:静态方法不能访问非静态变量

原因:因为在内存当中,是先有静态的内容,后有非静态的内容,“先人不知道后人,而后人知道先人”

示例:比如在以下代码中, 静态方法methodStatic不能打印出普通成员变量num

public class MyClass {
    int num = 5; //普通成员变量
    static int staticNum = 6;  //静态成员变量

    public void method(){
        System.out.println("这是一个普通成员方法");
        System.out.println(num);  //可以
        System.out.println(staticNum);  //可以
    }

    public static void methodStatic(){
        System.out.println("这是一个静态成员方法");
        System.out.println(staticNum); //可以
        System.out.println(num);  //报错,不可以访问普通成员变量num
    }
}

第二:静态方法中不能有this

原因:this代表当前对象,可静态跟对象没关系,只跟类有关系

示例:在下面的代码中,根本无法打印this的内容

public class MyClass {

    public static void methodStatic(){
        System.out.println("这是一个静态成员方法");
        //静态方法不能使用this
        System.out.println(this);  //错误写法
    }
}

  1. 静态代码块(了解)

4.1 静态代码块的格式
public class 类名称{
    static{
        //静态代码块的内容
    }
}

4.2 静态代码块的特点
当第一次用到本类时,静态代码块执行唯一的一次

4.3 代码说明
先创建一个person类,并在里面写一个static代码块和无参构造函数
public class person {
    //静态代码块
    static{
        System.out.println("静态代码快执行");
    }

    //无参构造函数
    public person(){
        System.out.println("构造函数执行");
    }
}

在main中使用person的构造函数
public class Demo03staticBlock {
    public static void main(String[] args) {
        //第一次使用person类,构造函数被执行,同时,静态代码块在这里会悄悄地执行唯一的一次
        person one = new person(); 
        //第二次使用到person类,构造函数被执行,静态代码块不知执行
        person two = new person();
    }
}

/*输出结果:
    静态代码快执行
    构造函数执行
    构造函数执行
*/

4.4 静态代码块的用途
静态代码块通常用于在类刚开始被使用时,对某些变量进行批量的赋值,在一些特定的工程中也具有重要的作用,在这里先做简单的了解。

点赞
收藏
评论区
推荐文章
codedecent codedecent
3年前
这道SQL有一点...不一样?
原题目从课程表(课程号,课程名)学生表(学号,年龄,性别,课程号,分数)中查询出平均分大于60分的学生的学号及课程成绩最初尝试一开始不太会做,直接在网络上搜索答案,找到的却只有这样的题目答案sqlSELECTsid,AVG(sscore)FROMscoreGROUPBYsidHAVINGavg(sscore)60单表操作
Wesley13 Wesley13
3年前
java类的属性
java类是一个面向对象的思想!!!!!!!!!!!!首先我们来创建一个Student类packagecuteSnow;publicclassStudent{//学生类型的属性,所有创建的学生对象都有以下的属性publicStringid;//学号publ
CuterCorley CuterCorley
4年前
C语言入门系列之10.结构体和共用体
一个国家IT技术最被寄予厚望的人,就是这个国家的程序员,是心中有梦想、眼里有希望,致敬最可爱、最可敬的年轻一代程序猿和程序媛。奔涌吧,程序员们,和1000万程序员一起,让中国变得更强。一、结构体变量的基本使用1.概述引入:有时需要将不同类型的数据组合成一个有机的整体,以便于引用。例如,一个学生有学号、姓名、性别、年龄、地址等属性,需要定义
Wesley13 Wesley13
3年前
SQL题目
Student(S,Sname,Sage,Ssex)学生表      S:学号;Sname:学生姓名;Sage:学生年龄;Ssex:学生性别Course(C,Cname,T)课程表                   C,课程编号;Cname:课程名字;T:教师编号SC(S,C,score)成绩表              
Easter79 Easter79
3年前
springboot2之优雅处理返回值
前言最近项目组有个老项目要进行前后端分离改造,应前端同学的要求,其后端提供的返回值格式需形如{"status":0,"message":"success","data":{}}方便前端数据处理。要实现前端同学这个需求,其实也挺简单的,
Stella981 Stella981
3年前
Python实现循环随机抽题
前几天有个同学问了我一个问题:现在班上共计有70名学生,题库中有20道题,每位同学随机抽5道题(不重复),该怎么用python实现这个功能?感兴趣的同学可以先不看下面的分析,试着自己实现一下这个功能。已经实现的同学或觉得有点问题的小伙伴,看看我的分析思路吧。1解题思路
Wesley13 Wesley13
3年前
Java高级特性2
\TOC\1\.static关键字1.1类变量、类方法/static关键字类变量不用实例化,直接类名.属性名就可以使用,是类的一部分,被所有这个类的实例化所共享,也可以叫做静态变量如果想让一个类的所有实例共享数据,就用类变量!
Wesley13 Wesley13
3年前
MySQL面试
范式1:原子性,表中的没一列都是不可分的,不能是数组,集合。范式2:在第一范式基础上,属性完全依赖于主键。范式3:非主属性不依赖于其它非主属性。(关系中不包含在其它关系中已包含的非主键信息)   比如Student表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)   这样一个表结构,就存在上述关系。 学号 所在院校
Wesley13 Wesley13
3年前
Java之面向对象3.1.3
publicclassPerson{      //成员变量   privateStringname; //姓名   privateintage;      //年龄      //公共的设置属性的方法:setter   publicvoidsetName(Stringname)
菜园前端 菜园前端
2年前
前端同学都了解什么是副作用么?
原文链接:什么是副作用?副作用会让一个函数变的不纯,纯函数是根据相同的输入返回相同的输出,如果函数依赖于外部的状态就无法保证输出相同,就会带来副作用。副作用来源函数依赖外部状态(变量),但是副作用不可能完全禁止,尽可能控制在它们可控范围内发生。缺点副作用使
Python进阶者 Python进阶者
10个月前
一篇文章带你弄懂Python基础之列表介绍和循环遍历
大家好,我是Go进阶者,今天给大家分享一些Python基础(列表基础和循环遍历介绍),一起来看看吧一、列表介绍想一想:字符串可以用来存储一串信息,那么想一想,怎样存储所有同学的名字呢?定义100个变量,每个变量存放一个学生的姓名可行吗?有更好的办法吗?答: