来自《原子习惯》的一句话:慢步前行,但决不后退。
目录
7. public static void main(String[] args)是什么含义?
1.static简介
static表示静态,是java中的一个修饰符,可以修饰成员变量,成员方法。
2.问题情景
针对于一个班的同学而言:每个同学的老师都是同一个老师。
在Java中,如果学生对象的属性有”老师名字“,创建两个学生对象,一个学生对象的“老师名字”属性被赋予了值,但是另一个学生对象的老师名字没有被赋值。
这就是不合理的地方:设置了一个同学的老师名字,另一个同学的老师名字也应该被设置(都是同一个老师)。
3.解决办法:使用静态变量
这里我们在JavaBean中用static修饰成员变量来解决这个问题,请看案例代码:
学生类:
//原本学生类的三个属性:姓名,年龄,性别
//这里加入新属性:老师的姓名
public class Student {
private String name;
private int age;
private String gender;
//老师的姓名,设置为public,可以直接使用对象.属性来引用
public static String teacherName;
public void study(){
System.out.println(name + "正在学习");
}
public void show(){
System.out.println(name+" "+ age+" "+gender+" "+teacherName);
}
public Student() {
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
}
测试类:
public class Test {
public static void main(String[] args) {
Student student1 = new Student("张三",23,"男");
Student student2 = new Student("李四",24,"男");
System.out.println("把Student类中的teacherName属性设置为static,把所有该类的对象的老师属性值共享");
student1.teacherName = "阿玮老师";
student1.show();
student2.show();
System.out.println("如果在JavaBean中设置属性为static:那么就能多出一种调用方式:直接使用类名调用(更加推荐这种方式):");
Student.teacherName="阿玮老师2";
student1.show();
student2.show();
}
}
输出结果:
4.static修饰成员变量在内存中的原理?
当把Student类的字节码文件加载到方法区时: 在内存当中创建了一个单独存放静态变量的空间(这叫做静态区,JDK8以后静态区在堆空间里面) 静态区里面存储着Student类里面所有的静态变量。 静态变量随着类加载,且优先于对象出现。 在上述demo131中: 如果先执行的是这一行代码: Student.teacherName="阿玮老师2"; 在执行代码后,内存中不会出现Student对象。只是加载了Student类的class文件与赋值了静态区中的static变量。 如果先执行的是这一行代码: Studentstudent1=newStudent("张三",23,"男"); 内存中会出现student对象;但是过程是先加载Student类的class文件,再存储静态区中的static变量,属性为空。 最后在堆内存中开辟对象空间(里面存储了所有非静态的成员变量)。 如果说student1想要找teacherName属性--就需要在静态区里面去寻找了 结论:以后需要把所有一个类的对象的某个属性都设置为相同值的时候:把该属性用static修饰
5.静态方法能够在哪里应用呢?
静态方法的应用:
1.多用在测试类(psvm)与工具类当中,JavaBean中很少使用。
2.静态方法推荐使用类名调用。
3.工具类:写工具类辅助自己的程序比如:MathUtils
4.工具类的内容:1.需要私有化构造方法(使外界不能创建该对象)2.方法都定义为静态(static修饰)方法方便调用,且不需要创建对象。
工具类(数组工具类:把数组变成特定字符串样式,求数组平均数)的案例代码:
public class ArrayUtil {
private ArrayUtil(){};
//static别忘加
public static String printArr(int[] arr){
StringJoiner sj = new StringJoiner(",","[","]");
for (int i = 0; i < arr.length; i++) {
//StringJoiner只能加字符串
sj.add(arr[i]+"");
}
return sj.toString();
}
public static double getAverage(double[] arr){
double sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum/arr.length;
}
}
测试类:
public class Test {
public static void main(String[] args) {
int[] arr1 = {1,2,3,4,5,6,7,8,9};
double[] arr2 = {1.1,2.2,3.3,4.4,5.5};
System.out.println("使用工具类名直接调用静态方法:");
System.out.println(ArrayUtil.printArr(arr1));
System.out.println(ArrayUtil.getAverage(arr2));
}
}
输出结果:
6.使用静态方法有是什么注意事项?
1.静态方法不能含this关键字 2.非静态方法中可以访问所有变量及方法,与之相比,静态方法中只能访问静态变量及方法
下面是案例代码:
学生类:
public class Student {
String name;
int age;
static String teacherName;
//这个方法在平时是简写的
//非静态方法和调用它的对象相关
public void show(Student this){
System.out.println("非静态方法能够访问方法调用者(this)的地址,也能访问非静态方法,非静态变量:\n"+this);
System.out.println(this.name+" "+age+" "+teacherName);
this.show1();
System.out.println("非静态方法中也能够调用静态方法:下面是非静态方法中调用的静态方法");
this.method();
}
public void show1(){
System.out.println("show非静态方法");
}
public static void show2(){
System.out.println("show静态方法");
}
public static void method(){
//静态方法中不能访问非静态变量,这个方法中不能调用name,age( 堆内存中的静态区里面不存这些)
//也不能调用show方法与show1方法
System.out.println("静态方法中只能访问静态变量及方法:\n"+teacherName);
show2();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Student.teacherName="阿玮老师";
Student s=new Student();
s.name="zhangsan";
s.age=23;
System.out.println("s1的地址:"+s);
s.show();
}
}
输出:
7. public static void main(String[] args)是什么含义?
public:被JVM调用,访问权限足够大 static:直接类名访问,不需要创建对象,因为main方法是静态的,所以测试类中的其他方法也需要是静态的 void: 被JVM调用,不需要返回值 main: 只有main才能被虚拟机识别 String[] args:用于接收录入的数据,为了向下兼容,现在仍然保留:这是字符串数组,默认情况下没有数据。
案例代码:
public class Test {
public static void main(String[] args) {
System.out.println("IDEA中右上角EditConfigurations中可以设置字符串数组内容");
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
输出: