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.5501
https://blog.csdn.net/TYRA9/article/details/128997395?spm=1001.2014.3001.5501
七、总结 :
🆗,以上就是关于static关键字的一些知识点分享。我们从雷电将军的“眼狩令”开始引入为什么需要static关键字。接着又详细分享了关于static修饰属性和行为的一些注意点,又举了诸如main函数形式解读和静态代码块这些static的具体应用。 感谢阅读!
System.out.println("END------------------------------------------------------------");
相关文章:
java static关键字 万字详解
目录 一、为什么需要static关键字: 二、static关键字概述 : 1.作用 : 2.使用 : 三、static修饰成员变量详解 : 1.特点 : 2.细节 : ①什么时候考虑使用static关键字? ②静态变量和非静态变量的区别? ③关于静态变量的初始化问题 : ④关于静态变…...
光谱实验反射、透射光谱测量
标题反射、透射光谱测量的基本原理 暗背景/基线:Dark………………………………………………………………0% (空)白参考:Reference…………………………………………………………100% 样品反射/透射光谱:Sampl…...
【基础算法】之 冒泡排序优化
冒泡排序思想基本思想: 冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来(假设从小到大),即为较大的数慢慢往后排,较小的数慢慢往前排。直观表达,每一趟遍历,…...
Python | 线程锁 | 3分钟掌握【同步锁】(Threading.Lock)
文章目录概念无锁加锁死锁解决死锁概念 threading.Lock 同步锁,可以用于保证多个线程对共享数据的独占访问。 当一个线程获取了锁之后,其他线程在此期间将不能再次获取该锁,直到该线程释放锁。这样就可以保证共享数据的独占访问,…...
Linux下安装MySQL8.0的详细步骤(解压tar.xz安装包方式安装)
Linux下安装MySQL8.0的详细步骤 第一步:下载安装配置 第二步:修改密码,并设置远程连接(为了可以在别的机器下面连接该mysql) 第三步:使用Navicat客户端连接 搞了一台云服务器,首先要干的活就是…...
leaflet 绘制多个点的envelope矩形(082)
第082个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中如何根据多边形的几个坐标点来绘制envelope矩形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共78行)安装插件相关API参考:专栏目标示例…...
CAJ论文怎么批量免费转换成Word
大家都知道CAJ文件吗?这是中国学术期刊数据库中的文件,这种文件类型比较特殊。如果想要提取其中的内容使用,该如何操作呢?大家可以试试下面这种免费的caj转word的方法,多个文档也可以一起批量转换。准备材料:CAJ文档、…...
面试必问: 结构体大小的计算方法
结构体大小的计算需同时满足以下几点 一、结构体成员的偏移量必须是当前成员大小的整数倍。(0是任何数的整数倍) 举一个例子 struct Test1{char a; // 当前偏移量为0,是char所占字节数1的整数倍 所以所占大小为1char b; …...
Java中super函数的用法
1 问题 Java中super函数有很多方法,在使用的时候我们应该如何正确区分? 2 方法 三种用法: 访问父类的方法。 调用父类构造方法。 访问父类中的隐藏成员变量。 class A{ int x,y; A(int x,int y){ System.out.println("A"); } } cla…...
第十一届“泰迪杯”数据挖掘挑战赛携“十万”大奖火热来袭
第十一届“泰迪杯”数据挖掘挑战赛 竞赛组织 主办单位: 泰迪杯数据挖掘挑战赛组织委员会 承办单位: 广东泰迪智能科技股份有限公司 人民邮电出版社 协办单位: 重庆市工业与应用数学学会、广东省工业与应用数学学会、广西数学学会、河北省工业…...
分享三个可以在家做的正规兼职工作,看到就是赚到
你可以在家做正式的兼职工作。在线兼职工作值得考虑,时间相对自由。在线兼职收入可能不如线下滴滴和外卖立竿见影,但仍然可以坚持收入。有些人比工作工资发展得更高。当然,天上不会有馅饼,不劳无获。那么有哪些正规的兼职可以在家…...
javaFx实现鼠标穿透画布,同时操作画布和桌面,背景透明,类似ppt批注
一、功能需要由来和大致效果 今天,我们要用javaFx来实现一个鼠标穿透画布的功能,该需求来自于在我们的javaFx桌面应用中,需要实现一个悬浮的桌面侧边工具栏,在工具栏中有画笔绘制,批注的功能,能够实现在任何…...
客户服务知识库的最佳实践7个步骤
每个公司的声誉都依赖于客户,如果客户因为想要购买你的产品找到你,但是了解到你的客户服务做的不好,可能也会放弃你的产品,就像市场营销依赖于潜在客户的关系一样,公司的服务部门也需要依赖于现有客户的关系࿰…...
多重继承的虚函数表
同一个类,不同对象使用同一张虚函数表 不同类使用不同的虚函数表 子类自己添加的虚函数(非重写),在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模式匹配
模式匹配 模式匹配是从函数式编程语言(例如:Haskell,Lisp)吸收而来的,用于为复杂的类型系统提供一个轻松的解构能力。rust使用match来提供模式匹配的功能。mathc类似于其它编程语言中的switch-case,但是远…...
GIT:【基础一】必要配置和命令
目录 一、Git安装 二、基础命令 1.git config -l:git配置详细信息 2.git config --system -l:本地git系统自动配置的信息 3.git config --global -l:本地git用户自动配置的信息 4.where git: windows查看git安装目录 5.git各配置…...
黑马程序员-Linux系统编程-01
课程链接 01-Linux命令基础习惯-Linux系统编程_哔哩哔哩_bilibili 课程重点笔记 01-linux命令基础习惯 终端 终端:一切输入、输出的总称,因此终端并不是一定指的是命令行,只要是能进行输入或者输出即可,但是在linux终端上‘’内…...
Python|每日一练|动态规划|图算法|散列表|数组|双指针|单选记录:不同路径|求两个给定正整数的最大公约数和最小公倍数|删除有序数组中的重复项
1、不同路径(数学,动态规划) 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”…...
Java常用框架(一)
思维导图 常见知识点 一、SpringBoot 1.简单介绍一下Spring及其优缺点 1.1 概念 重量级企业开发框架EJB的替代品,通过依赖注入、面向切面编程,使用简单Java对象POJO为企业Java开发提供了相对简单的方法。 1.2 优缺点 1.2.1 优点 组件代码轻量级 …...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
