当前位置: 首页 > news >正文

java static关键字 万字详解

目录

一、为什么需要static关键字:

二、static关键字概述 : 

        1.作用 : 

        2.使用 : 

三、static修饰成员变量详解 : 

        1.特点 : 

        2.细节 : 

                ①什么时候考虑使用static关键字?

                ②静态变量和非静态变量的区别?

                ③关于静态变量的初始化问题 : 

                ④关于静态变量的生命周期 : 

                ⑤关于公有静态常量 : 

        3.演示 : 

                ①对于静态变量和非静态变量访问方式的演示 : 

                ②对访问静态变量时需遵循访问权限的演示 : 

                ③对“眼狩令”问题中管账儿写的代码做出改进 : 

                ④对“培训机构收钱统计”的模拟演示 : 

                ⑤公有静态常量演示 : 

四、static修饰成员方法详解 : 

        1.静态方法 : 

        2.静态方法的使用场景 : 

        3.静态方法的生命周期 : 

        4.静态方法的案例演示 : 

        5.静态成员的特点总结 :

五、深入理解main函数(main形式说明) : 

        1.main形式回顾 :

        2.main形式解析 :

                ①为什么访问权限修饰符是public?

                ②为什么要用static修饰?

                ③关于返回值类型 :

                ④关于形参列表 :

                ⑤关于main函数中调用本类成员的问题 :

六、关于静态代码块的说明 : 

七、总结 : 


一、为什么需要static关键字:

 

        给大家举一个简单的例子吧。雷电将军自从发布了眼狩令以后,由于夺取的神之眼越来越多,将军幕府做账的没一会儿就算不清了。幸好,新来的管账儿会用Java,就自告奋勇地想用Java帮雷电将军编个小程序。以下是他写的代码 : 

package knowledge.polymorphism.about_static.eyecut;public class Captive {      //Captive,俘虏的意思;代表被缴获神之眼的对象。private String name;public Captive() {};public Captive(String name) {this.name = name;}public void setName() {this.name = name;}public String getName() {return name;}public void recycle_eyes() {System.out.println(getName() + "的神之眼被收回🌶!");}
}
class Recycle {public static void main(String[] args) {int count = 0;              //count变量用于统计累计收回的神之眼的数量。Captive wanye = new Captive("万叶");wanye.recycle_eyes();++count;Captive shenli = new Captive("神里凌华");shenli.recycle_eyes();++count;Captive heart_sea = new Captive("珊瑚宫心海");heart_sea.recycle_eyes();++count;//...............................System.out.println("--------------------------------------------");System.out.println("当前已回收了" + count + "枚神之眼.");}
}

        运行结果 : 

        可以看到,管账儿的思路还是很清晰的。他通过创建Captive类对象来代表被回收了神之眼的对象。又在main方法中定义了count变量存储已缴获神之眼的数量,并且每缴获一枚神之眼就让count变量自增加一。

        但是,大家看完这段代码后,有没有感觉有丶不对劲?
        就up自己来说,我看完这段代码后想提出两个疑问——
        ①.从count变量的用途来看,它与Captive类有着较为密切的关系,但count变量却定义在了Captive类之外。这是否违背了OOP编程的基本理念?
        ②.count变量定义在了Recycle类的main方法中,如果以后我们想单独调用count变量,该怎么整?
        诶,这显然是不可回避的两个问题。那么,怎么避免这种情况呢?这不,我们的static关键字来了,今天咱们就给管账儿的好好上一课。

二、static关键字概述 : 

        1.作用 : 

                static,静止的,静态的。static关键字可用于修饰类的成员

        修饰成员变量时,将被修饰的成员变量称为“类变量”,或者“静态变量”,“静态属性”。

        修饰成员方法时,将被修饰的成员方法称为“类方法”,或者“静态方法”。

        2.使用 : 

                使用static非常简单,我们只需要在定义成员变量或者成员方法时,在它们之前加上一个“static”即可。但要注意,平时我们在定义这些类的成员时,往往也会用访问权限修饰符修饰,那static关键字要写到访问权限修饰符之前呢还是之后呢?
                答案是都可以,但是up建议大家写在访问权限修饰符之后,既符合绝大多数程序🐒的编程习惯,也符合IDEA默认的一个顺序,如下所示 :

    //修饰成员变量private static String name;//修饰成员方法public static String getName() {return name;}

                 那如何调用我们定义好的这些“类变量” 和 “类方法” 呢?

        调用类变量——类名.成员变量名;

        调用类方法——类名.成员方法名(形参);

        //其实也可以通过对象来调用。

三、static修饰成员变量详解 : 

        1.特点 : 

                ①被static修饰修饰的成员变量,也就是类变量,被本类所有对象共享——即该类所有对象都可以对它进行二次更改

                ②JDK8.0开始,static修饰的成员变量位于堆空间中
                说明 : 当类加载器将含有static修饰的成员变量的类加载到方法区时,会根据反射机制生成一个字节码文件对象,即Class对象。Class对象在堆空间中,而static变量保存在Class实例的尾部。如下图所示 : (即所有对象访问的某个类变量,其实就是那一份

        2.细节 : 

                ①什么时候考虑使用static关键字?

                        当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量)。比如 : 某个Java培训机构要统计所有学员的累计交费总额,就可以在学员类中将学费属性设置为静态属性。再比如我们开篇举的雷电将军眼狩令的例子,我们可在俘虏类中定义count静态属性,每个俘虏类对象共享count变量。

                ②静态变量和非静态变量的区别?

                        静态变量被该类所有对象共享;而非静态变量是被每个对象独享。        
                        内存角度 : 
                        静态变量在堆空间的Class实例中,该类所有对象都是通过地址值继而找到Class实例中真正的类变量,它们共享的某个静态变量,是唯一的;而非静态变量是每创建一个新对象,都会在堆空间开辟空间,并且这块空间的一部分会用来存储非静态变量的内容,所以每个对象都各自有各自的非静态变量,不唯一
                        访问方式 : 
                        在上文static的使用中,我们提了一嘴——类变量既可以通过“类名.”的形式来调用,也可以通过“对象.”的形式来调用,但是建议大家优先使用“类名.”的形式来访问类变量。这里还要补充一点:在访问类变量时,也要遵循访问权限修饰符的规则。比如,如果某个类的一个静态属性为私有的,那么你就不能在其他类中直接访问这个静态属性。
                        而对于非静态属变量,非静态变量不能通过“类名.”的形式来访问,只能通过“对象.”的形式来访问。并且非静态属性的访问也要遵循访问权限修饰符的规则。

                ③关于静态变量的初始化问题 : 

                        静态变量的初始化在类加载时就已经执行完毕了。因此,静态变量的使用与是否创建了该类对象无关,只与该类是否加载有关;只要静态变量所在的类加载完毕,就可以使用该类的静态变量了。

                ④关于静态变量的生命周期 : 

                        如上一条所述。类变量的生命周期是随着类的加载开始,并随着类的回收而消亡的,与对象无关

                ⑤关于公有静态常量 : 

                        随意修改静态变量的值在某些情况下是有危险的,因此,为了降低风险,可以同时用final关键字修饰静态变量(一般写在static之后),使其称为静态常量;若想要让这个静态常量为大家所共同使用,可以使用public访问权限修饰符进行修饰,即公有静态常量。如下 : 

//静态常量final static String name = "Cyan";
//公有静态常量public static final String sex = "male";


                        对于静态常量来说,只能通过在定义时为其赋初值;或者先定义,在静态代码块中为其赋值的方法来进行初始化。不可以在构造器中进行静态常量的初始化。原因其实也很简单,静态属性的初始化是随着类的加载就执行完毕的,而构造器是在初始化对象时才会被调用,你加载类时发现这个静态属性没有初始化,就是不行。(PS : 关于静态代码块,文章后面up附上了链接,这里大家先了解一下即可)
                        而且在单独调用静态常量时,如果该静态常量在定义时就进行了初始化,则不会引起类的加载,这是因为jvm在编译阶段对类做了编译优化。但如果在定义静态常量时没有直接进行初始化,而是在静态代码块中进行了初始化,那么调用该静态常量时,其所在的类还是会被加载。(其特征就是类中的静态代码块被执行

        3.演示 : 

                ①对于静态变量和非静态变量访问方式的演示 : 

                up以Sample_1类作为第一个演示类,以Test_1类作为测试类。老规矩,为了简洁,up将Test_1类写在了Sample_1类的源文件中,Sample_1类,Test_1类代码如下

package knowledge.polymorphism.about_static.fields;public class Sample_1 {//静态成员变量static String name_1;//非静态成员变量String name_0;
}class Test_1 {public static void main(String[] args) {//访问静态变量//通过类名访问Sample_1.name_1 = "Cyan";System.out.println("类名.name_1 = " + Sample_1.name_1);System.out.println("-----------------------------------------");//通过对象访问Sample_1 s1 = new Sample_1();       //s1对象System.out.println("s1's name_1 = " + s1.name_1);Sample_1 sp1 = new Sample_1();      //ss1对象System.out.println("sp1's name_1 = " + sp1.name_1);System.out.println("-----------------------------------------");//某个对象修改了静态变量的值,其他所有对象再次访问时,即是修改后的值。sp1.name_1 = "Rain";System.out.println("s1's name_1 = " + s1.name_1);System.out.println("sp1's name_1 = " + sp1.name_1);System.out.println("-----------------------------------------");//访问非静态变量//只能通过对象访问s1.name_0 = "Five";System.out.println("s1's name_0 = " + s1.name_0);//Sample_1.name_0;    //这么访问会报错,因为非静态变量不能通过类名来访问。System.out.println("sp1's name_0 = " + sp1.name_0);}
}

                运行结果 : 

                 通过代码和运行结果我们可以看出,当我们更改了静态变量的值时,所有对象访问该静态变量都是修改后的值。而对于非静态变量,一个对象更改了其非静态变量的值后,丝毫不会影响另一个对象访问自己的非静态变量时的值。

                ②对访问静态变量时需遵循访问权限的演示 : 

                up以Sample_2类作为第二个演示类,以Test_2类作为测试类。
                Sample_2类,Test_2类代码如下 : 

package knowledge.polymorphism.about_static.fields;public class Sample_2 {//私有的静态变量private static String color = "Cyan";//默认的静态变量static double score = 411;
}class Test_2 {public static void main(String[] args) {//System.out.println("color = " + Sample_2.color);System.out.println("score = " + Sample_2.score);}
}

                运行结果 : 

                如代码所示,我们在Sample_2类中定义了两个静态变量。score变量无访问修饰符,默认本包下可以使用。我们当然可以在Test_2类中直接访问score变量;而对于color变量,color变量为Sample_2类私有的成员变量,因此不能直接跨类使用。如果你想在Test_2类中直接调用color变量,就会报错,如下图所示

                ③对“眼狩令”问题中管账儿写的代码做出改进 : 

                改进后的代码如下 : (注意count变量的变化)

package knowledge.polymorphism.about_static.eyecut;/** Captive,俘虏的意思;代表被缴获神之眼的对象。*/
public class Captive {private String name;static int count = 0;  //count变量用于统计累计收回的神之眼的数量。public Captive() {};public Captive(String name) {this.name = name;}public void setName() {this.name = name;}public String getName() {return name;}public void recycle_eyes() {System.out.println(getName() + "的神之眼被收回🌶!");}
}
class Recycle {public static void main(String[] args) {Captive wanye = new Captive("万叶");wanye.recycle_eyes();++Captive.count;Captive shenli = new Captive("神里凌华");shenli.recycle_eyes();++Captive.count;Captive heart_sea = new Captive("珊瑚宫心海");heart_sea.recycle_eyes();++Captive.count;//...............................System.out.println("--------------------------------------------");System.out.println("当前已回收了" + Captive.count + "枚神之眼.");}
}

                运行结果 : 

                 如代码所示,我们将原先在Recycle类main方法中的count变量定义到了Captive类中,并且将count变量设置为了静态变量。那么首先,负责统计Captive对象累计被回收神之眼的数量的count变量与Captive类之间有了关系。其次,将来便可以直接通过Captive类的类名来访问count变量,也有利于程序将来的扩展。

                ④对“培训机构收钱统计”的模拟演示 : 

                up以Student类作为第四个演示类,以Charge类作为测试类。我们在Student类中定义tuition静态变量用于存储总的学费
                Student类,Charge类代码如下 : 

package knowledge.polymorphism.about_static.fields;public class Student {static double tuition = 0;      //静态变量tuition,用于存储总的学费private String name;            //学生的姓名private String ID;              //学生的IDprivate String project;         //学生的交费项目public Student(String name, String ID, String project) {this.name = name;this.ID = ID;this.project = project;}public void showTuition() {System.out.println("当前累计收学费 " + tuition + " RMB.");}
}class Charge {public static void main(String[] args) {//创建学生对象,并修改学生类中静态变量tuition的值。Student cyan = new Student("Cyan", "20210001", "Spring Boot");System.out.println("0001号学员Cyan,学习Spring Boot,花费10000.");Student.tuition += 10000;cyan.showTuition();System.out.println("---------------------------------------");Student five = new Student("Five", "20210002", "mysql");System.out.println("0002号学员Cyan,学习mysql,花费5500.");Student.tuition += 5500;five.showTuition();System.out.println("---------------------------------------");Student rain = new Student("Rain", "20210003", "k8s");System.out.println("0003号学员Rain,学习k8s,花费3700.");Student.tuition += 3700;rain.showTuition();}
}

                运行结果

                ⑤公有静态常量演示 : 

                up以Demo类为第五个演示类。以Test_5为测试类。演示内容分为两部分,第一部分我们演示一下静态常量的初始化,第二部分演示一下调用静态常量时引起的类的加载的问题
                第一部分 : 
                Demo类,Test_5类代码如下 : 

package knowledge.polymorphism.about_static.fields;public class Demo {//静态常量static final String name = "Cyan";//公有静态常量public static final int age = 20;//关于静态常量的初始化://1.在定义时就初始化,就像我们上面写得一样.//2.在静态代码块中初始化,如下 :public static final String sex;static {sex = "male";}//3.PS : 静态常量不能在构造器中初始化,如下是错误的写法 :/*   public static final String hobby;public Demo() {hobby = "basketball";}
*/}
class Test_5 {public static void main(String[] args) {System.out.println("name = " + Demo.name);System.out.println("age = " + Demo.age);System.out.println("sex = " + Demo.sex);}
}

                运行结果

                第二部分 : 

                Demo类,Test_5类代码如下 : 
                我们先在Demo类中定义一个静态常量hobby,并且在定义时就给它赋初值。接着在测试类中调用这个静态常量,看看静态代码块中的内容会不会被执行。

package knowledge.polymorphism.about_static.fields;public class Demo {//测试————关于调用类的静态常量时,类的加载问题//静态常量在定义时已经初始化static final String hobby = "music";static {System.out.println("这句话输出,说明第一个静态代码块被执行");System.out.println("hobby = " + hobby);}
}
class Test_5 {public static void main(String[] args) {//直接调用hobby静态常量System.out.println("hobby = " + Demo.hobby);}
}

                 运行结果

                可以看到,在输出语句中调用了静态常量hobby,但是类中的静态代码块并没有被执行,说明调用hobby静态常量并没有导致类的加载

                接着,我们再来定义一个静态常量color,并在另一个静态代码块中为其赋初值。在测试类中调用该静态常量,测试静态代码块中的内容会不会执行。
                Demo类,Test_5类代码如下

package knowledge.polymorphism.about_static.fields;public class Demo {//测试————关于调用类的静态常量时,类的加载问题//静态常量在定义时已经初始化static final String hobby = "music";static {System.out.println("这句话输出,说明第一个静态代码块被执行");System.out.println("hobby = " + hobby);System.out.println("-----------------------------------");}//静态常量在定义时未初始化,而是在静态代码块中完成了初始化static final String color;static {color = "cyan";System.out.println("这句话输出,说明第二个静态代码块被执行");System.out.println("color = " + color);System.out.println("-----------------------------------");}
}
class Test_5 {public static void main(String[] args) {System.out.println("hobby = " + Demo.hobby);System.out.println("color = " + Demo.color);}
}

                 运行结果 : 

                我们来分析一下输出结果 : 
                首先,main函数第一条输出语句中调用了Demo.hobby,hobby是静态常量,并且是个在定义时就已经赋了初值的静态常量,因此调用Demo.hobby时不会加载类静态代码块中的语句也就不会执行。但是,main函数第二条输出语句中调用了Demo.color,color也是静态常量,但它是个在定义时没有赋初值,而在静态代码块中才进行了初始化的静态常量,因此调用Demo.color时会加载类,静态代码块随着类的加载而被执行。因此,控制台上按照定义的顺序先后打印出了两个代码块中的内容。类加载后,才打印出了输出语句中的color变量。

四、static修饰成员方法详解 : 

        1.静态方法 : 

                static关键字修饰的成员方法,称为静态方法 或 类方法(只需在非静态方法的访问权限修饰符后面增加一个static关键字即可)。调用静态方法同调用静态变量类似,既可以通过对象来调用,也可以通过类名来调用,当然,一般情况下均使用类名调用
                需要注意的是——静态方法中没有引用this,也没有super。因此,在静态方法中不能访问非静态成员而在非静态方法,是可以访问静态成员和非静态成员的。当然,以上两点都必须在满足访问权限修饰符的前提下。(一定要牢记红色加粗字体)                                

        2.静态方法的使用场景 : 

                只需要访问静态成员,且不涉及到任何和对象相关的成员,所需参数均可由形参列表显式提供,这时候我们就可以定义静态方法
                up光这么说多少有些抽象,大家可以想想静态方法的特点——静态方法可以通过类名来调用,无需创建对象,要不为啥叫类方法。其实就是这么回事儿。比如我们有名的工具类Arrays类,打开Arrays类的源码,查看它的Structure你会发现,Arrays类中定义非常多的方法,而且它们无一例外都是静态方法,如下GIF所示

                 其实,判断这些方法是不是静态方法不需要一个一个地点开查看,有个小技巧——注意看上面演示图中——每个方法的图标左下角都有一个类似于镂空菱形的小玩意儿,其实这就表示该方法用了static修饰。你也可以自己试着写一个方法验证一下。
                话说回来,当我们使用Arrays类的这些方法时,比如我们最常见的toString(),或者sort() 等方法,我们不需要创建Arrays类对象,而是直接通过类名来调用——“Arrays.toString()”,“Arrays.sort()”,等等。这就是静态方法的使用场景,要不为什么管Arrays类叫工具类呢。

        3.静态方法的生命周期 : 

                静态方法和非静态方法都是随着类的加载开始,将结构信息存储在方法区,并随着类的回收而消亡

        4.静态方法的案例演示 : 

                说实话,也没啥演示的😂。给大家演示一下工具类静态方法的调用和自定义静态方法的调用吧。up以TestStaticMethod类和Demo类为栗,我们在TestStaticMethod类中定义一个数组,并用Arrays类的sort方法对其进行排序,再遍历排序后的数组。在Demo类中定义一个静态方法,然后在TestStaticMehtod类中的main方法中利用类名来调用该静态方法。
                TestStaticMethod类和Demo类代码如下

package knowledge.polymorphism.about_static.method;import java.util.Arrays;public class TestStaticMethod {public static void main(String[] args) {int[] array = new int[]{11, 5, 2, 985, 211, 5};//调用Arrays类的静态方法sort() 对当前数组进行正向排序。Arrays.sort(array);for (int i = 0; i < array.length; i++) {System.out.println("数组第" + (i + 1) + "个元素是:" + array[i]);}System.out.println("---------------------------------------");//调用自己瞎jb写的静态方法Demo.roll_up();}
}
class Demo {//在Demo类中定义一个静态方法,该方法仅作为演示,无实际意义public static void roll_up() {System.out.println("卷死👴了!");}
}

        5.静态成员的特点总结 :

        静态成员不依赖于类的特定实例,被类的所有实例共享,就是说static关键字修饰的成员变量或者成员方法不需要依赖于对象来进行访问,只取决于类是否被加载,只要这个类被加载,jvm就可以根据类名找到它们,直接“类名.___”的形式就可以调用。

五、深入理解main函数(main形式说明) : 

        1.main形式回顾 :

        public static void main(String[] args) {
                //方法体(代码)
        }

                Δmain函数是所有程序的唯一入口,由jvm来调用。

public class Demo_main {public static void main(String[] args) {//Codes}
}

        2.main形式解析 :

                ①为什么访问权限修饰符是public?

                因为main函数是一切程序的入口,jvm需要调用类的main() 方法来开启一个程序的执行。而jvm要想调用main() 方法,就必须要求main() 方法是公共的,否则不满足jvm的访问条件如果我们去掉main函数前面的public修饰符,main函数将无法被jvm执行,如下GIF图演示 :

                ②为什么要用static修饰?

                在static关键字的万字详解篇中,我们提到了静态方法的使用场景——当我们只需要访问静态成员,不需要访问该类对象的状态,和该类的对象并无什么瓜葛时,可以在该类中根据需要定义若干静态方法。我们也举了Arrays类等工具类的例子。

                回到main函数上,对于main函数所在的类,jvm并不需要创建该类的对象或者访问该类对象的状态,jvm的目的就是直接访问main函数,所以main函数必须设置为static类型——静态方法。其实前提都是因为main函数的作用——充当程序的唯一入口。

                一样的,如果我们去掉main函数前面的static关键字,main函数将无法被jvm执行如下GIF图演示 :

                ③关于返回值类型 :

                jvm仅将main函数当作程序的入口来使用,不需要你返回任何值,自然main函数的返回值类型定义为void类型。举一个不是特别恰当的例子:你把马桶当作程序,马桶盖子当作main函数。那么,你平时大号是不是都需要先找到马桶盖子,然后打开,后面up就不做详细阐述了,反正打开马桶盖必须是首要条件,而且再经过你的一系列操作,最后结束,再盖上马桶盖子。我想,你不会希望在你大号完毕后,马桶再给你吐出一些东西来吧😅?其实就是一个道理。

                ④关于形参列表 :

                main函数的形参是“String[] args”,显然args表示一个String类型的数组。但是要知道,main函数是jvm来调用的,因此想直接传入实参还没那么容易。有两种途径可以解决 :

                ①DOS命令,不知道大家还记不记得😂。就是cmd那黑窗口。在DOS中给main函数传入实参的使用格式如下 :

java 运行的类型 第一个参数 第二个参数 第三个参数 第四个参数 第五个参数......

                传入的参数之间要在分割处打空格。给大家举个例子演示一下 :

                up在桌面新建了一个txt文件,文件重命名给它改成.java后缀,如下图所示 :

                在Demo.java文件中写入“输出args数组内容”的代码如下图所示 : (因为up使用DOS存在乱码问题,因此这里只能使用英文了,望理解😂。

                然后按下win + R进入运行界面,在运行界面中输入CMD进入DOS界面;接着,在DOS界面输入 "cd Desktop" 命令敲回车进入桌面,然后通过javac命令进行编译,编译后就可以使用java命令运行了如下GIF图演示(===分多张图演示===) :

                在演示的GIF图中大家可以看到,Demo.java文件编译后,up在运行时手动传入了三个实参Cyan,Rain和TY,并且都随着打印args数组的语句的执行而成功输出了。

                ②IDEA设置。要想在IDEA中也达到类似的——手动给main函数传入实参的效果,需要你单独更改类的Program arguments。大家可以在IDEA的Run(运行)一栏,依次点击Run ---> Edit Configurations ---> 找到Program arguments,然后在Program arguments一栏中手动给出当前类main函数的实参,多个实参中间仍然以空格分割

                up以Demo_main为例,如下GIF演示图所示(分多张演示图) :

 

                可以看到,在未设置参数时直接运行Demo_main类,无输出结果;而通过更改Program arguments参数,成功打印出了args数组中传入的实参

                ⑤关于main函数中调用本类成员的问题 :

                我们可以在main函数中直接调用本类的静态成员(类变量和类方法)

up还是以Demo_main类举个栗子吧,Demo_main类代码如下 :

package knowledge.polymorphism.mainEX;public class Demo_main {private static String name = "Cyan";public static void Haha() {System.out.println("哈哈哈哈哈哈哈哈哈");}public static void main(String[] args) {Haha();System.out.println("name = " + name);}
}

                运行结果 :

                如图所示,main方法调用本类的静态成员不需要通过类名的形式,而是直接用就可以。

                ②main函数并不能直接访问本类的非静态成员。

                如果你非想访问,必须在main函数中创建一个该类的对象,然后再通过对象的形式去访问类中的非静态成员。仍以Demo_main类为栗,Demo_main类代码如下 :

package knowledge.polymorphism.mainEX;public class Demo_main {private String name = "Cyan";public  void Haha() {System.out.println("哈哈哈哈哈哈哈哈哈");}public static void main(String[] args) {Demo_main demo_main = new Demo_main();demo_main.Haha();System.out.println("name = " + demo_main.name);}
}

                运行结果 :

                🆗, 以上就是对main函数形式上的一些解释。

六、关于静态代码块的说明 : 

        "静态代码块"相关部分讲解非常详细,因此篇幅较长。为了避免影响大家的阅读体验,up把关于java 代码块的一些说明单独拎了出来,链接如下

https://blog.csdn.net/TYRA9/article/details/128997395?spm=1001.2014.3001.5501https://blog.csdn.net/TYRA9/article/details/128997395?spm=1001.2014.3001.5501

七、总结 : 

        🆗,以上就是关于static关键字的一些知识点分享。我们从雷电将军的“眼狩令”开始引入为什么需要static关键字。接着又详细分享了关于static修饰属性和行为的一些注意点,又举了诸如main函数形式解读和静态代码块这些static的具体应用。 感谢阅读!

                System.out.println("END------------------------------------------------------------");

相关文章:

java static关键字 万字详解

目录 一、为什么需要static关键字&#xff1a; 二、static关键字概述 : 1.作用 : 2.使用 : 三、static修饰成员变量详解 : 1.特点 : 2.细节 : ①什么时候考虑使用static关键字? ②静态变量和非静态变量的区别&#xff1f; ③关于静态变量的初始化问题 : ④关于静态变…...

光谱实验反射、透射光谱测量

标题反射、透射光谱测量的基本原理  暗背景/基线&#xff1a;Dark………………………………………………………………0%  &#xff08;空&#xff09;白参考&#xff1a;Reference…………………………………………………………100%  样品反射/透射光谱&#xff1a;Sampl…...

【基础算法】之 冒泡排序优化

冒泡排序思想基本思想: 冒泡排序&#xff0c;类似于水中冒泡&#xff0c;较大的数沉下去&#xff0c;较小的数慢慢冒起来&#xff08;假设从小到大&#xff09;&#xff0c;即为较大的数慢慢往后排&#xff0c;较小的数慢慢往前排。直观表达&#xff0c;每一趟遍历&#xff0c;…...

Python | 线程锁 | 3分钟掌握【同步锁】(Threading.Lock)

文章目录概念无锁加锁死锁解决死锁概念 threading.Lock 同步锁&#xff0c;可以用于保证多个线程对共享数据的独占访问。 当一个线程获取了锁之后&#xff0c;其他线程在此期间将不能再次获取该锁&#xff0c;直到该线程释放锁。这样就可以保证共享数据的独占访问&#xff0c…...

Linux下安装MySQL8.0的详细步骤(解压tar.xz安装包方式安装)

Linux下安装MySQL8.0的详细步骤 第一步&#xff1a;下载安装配置 第二步&#xff1a;修改密码&#xff0c;并设置远程连接&#xff08;为了可以在别的机器下面连接该mysql&#xff09; 第三步&#xff1a;使用Navicat客户端连接 搞了一台云服务器&#xff0c;首先要干的活就是…...

leaflet 绘制多个点的envelope矩形(082)

第082个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中如何根据多边形的几个坐标点来绘制envelope矩形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共78行)安装插件相关API参考:专栏目标示例…...

CAJ论文怎么批量免费转换成Word

大家都知道CAJ文件吗&#xff1f;这是中国学术期刊数据库中的文件&#xff0c;这种文件类型比较特殊。如果想要提取其中的内容使用&#xff0c;该如何操作呢&#xff1f;大家可以试试下面这种免费的caj转word的方法,多个文档也可以一起批量转换。准备材料&#xff1a;CAJ文档、…...

面试必问: 结构体大小的计算方法

结构体大小的计算需同时满足以下几点 一、结构体成员的偏移量必须是当前成员大小的整数倍。&#xff08;0是任何数的整数倍&#xff09; 举一个例子 struct Test1{char a; // 当前偏移量为0&#xff0c;是char所占字节数1的整数倍 所以所占大小为1char b; …...

Java中super函数的用法

1 问题 Java中super函数有很多方法&#xff0c;在使用的时候我们应该如何正确区分&#xff1f; 2 方法 三种用法&#xff1a; 访问父类的方法。 调用父类构造方法。 访问父类中的隐藏成员变量。 class A{ int x,y; A(int x,int y){ System.out.println("A"); } } cla…...

第十一届“泰迪杯”数据挖掘挑战赛携“十万”大奖火热来袭

第十一届“泰迪杯”数据挖掘挑战赛 竞赛组织 主办单位&#xff1a; 泰迪杯数据挖掘挑战赛组织委员会 承办单位&#xff1a; 广东泰迪智能科技股份有限公司 人民邮电出版社 协办单位&#xff1a; 重庆市工业与应用数学学会、广东省工业与应用数学学会、广西数学学会、河北省工业…...

分享三个可以在家做的正规兼职工作,看到就是赚到

你可以在家做正式的兼职工作。在线兼职工作值得考虑&#xff0c;时间相对自由。在线兼职收入可能不如线下滴滴和外卖立竿见影&#xff0c;但仍然可以坚持收入。有些人比工作工资发展得更高。当然&#xff0c;天上不会有馅饼&#xff0c;不劳无获。那么有哪些正规的兼职可以在家…...

javaFx实现鼠标穿透画布,同时操作画布和桌面,背景透明,类似ppt批注

一、功能需要由来和大致效果 今天&#xff0c;我们要用javaFx来实现一个鼠标穿透画布的功能&#xff0c;该需求来自于在我们的javaFx桌面应用中&#xff0c;需要实现一个悬浮的桌面侧边工具栏&#xff0c;在工具栏中有画笔绘制&#xff0c;批注的功能&#xff0c;能够实现在任何…...

客户服务知识库的最佳实践7个步骤

每个公司的声誉都依赖于客户&#xff0c;如果客户因为想要购买你的产品找到你&#xff0c;但是了解到你的客户服务做的不好&#xff0c;可能也会放弃你的产品&#xff0c;就像市场营销依赖于潜在客户的关系一样&#xff0c;公司的服务部门也需要依赖于现有客户的关系&#xff0…...

多重继承的虚函数表

同一个类,不同对象使用同一张虚函数表 不同类使用不同的虚函数表 子类自己添加的虚函数(非重写),在VS中是将此放在第一个继承类的虚函数表里. #include <iostream> using namespace std;class Father { public:virtual void func1() { cout << "Father::f…...

第11篇:Java开发工具使用和代码规范配置

目录 1、IntelliJ IDEA 简介 2. IntelliJ IDEA 下载 3. IntelliJ IDEA 安装和使用 3.1 安装到Windows下 3.2 快速编写 Hello World 程序...

Rust模式匹配

模式匹配 模式匹配是从函数式编程语言&#xff08;例如&#xff1a;Haskell&#xff0c;Lisp&#xff09;吸收而来的&#xff0c;用于为复杂的类型系统提供一个轻松的解构能力。rust使用match来提供模式匹配的功能。mathc类似于其它编程语言中的switch-case&#xff0c;但是远…...

GIT:【基础一】必要配置和命令

目录 一、Git安装 二、基础命令 1.git config -l&#xff1a;git配置详细信息 2.git config --system -l&#xff1a;本地git系统自动配置的信息 3.git config --global -l&#xff1a;本地git用户自动配置的信息 4.where git&#xff1a; windows查看git安装目录 5.git各配置…...

黑马程序员-Linux系统编程-01

课程链接 01-Linux命令基础习惯-Linux系统编程_哔哩哔哩_bilibili 课程重点笔记 01-linux命令基础习惯 终端 终端&#xff1a;一切输入、输出的总称&#xff0c;因此终端并不是一定指的是命令行&#xff0c;只要是能进行输入或者输出即可&#xff0c;但是在linux终端上‘’内…...

Python|每日一练|动态规划|图算法|散列表|数组|双指针|单选记录:不同路径|求两个给定正整数的最大公约数和最小公倍数|删除有序数组中的重复项

1、不同路径&#xff08;数学&#xff0c;动态规划&#xff09; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”…...

Java常用框架(一)

思维导图 常见知识点 一、SpringBoot 1.简单介绍一下Spring及其优缺点 1.1 概念 重量级企业开发框架EJB的替代品&#xff0c;通过依赖注入、面向切面编程&#xff0c;使用简单Java对象POJO为企业Java开发提供了相对简单的方法。 1.2 优缺点 1.2.1 优点 组件代码轻量级 …...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...