Static关键字
有的时候在方法前加static关键字,有的时候不加,是否添加static涉及类的加载顺序。
具有static的方法可以调用同样具有static的方法,无法调用没有static的方法,具体原因和Java中类和对象的关系有关。
Java类和对象的关系
类是构建对象的模板,一个类可以构建多个对象。
static修饰的变量和方法都是属于类的,类独有的,不属于对象,也不会当作模板的内容放在对象中。
public class Person{
private String name;
private int age;
private static String from;
public static void main(String[]args){
Person zhangsan = new Person;
zhangsan.age = 18;
zhangsan.name = "zhangsan";
zhangsan.from = "China";
Person lisi = new Person;
lisi.age = 20;
lisi.name = "lisi";
lisi.from = "USA";
System.out.println(zhangsan.name + " " + zhangsan.age + " " +zhangsan.from);
System.out.println(lisi.name + " " + lisi.age + " " +lisi.from);
}
}
/* 该函数输出结果为
zhangsan 18 USA
lisi 20 USA
*/
上述示例中,我们发现不管是zhangsan还是lisi,他们的from都是USA,而zhangsan的from应该输出China才对,分析这其中的原因:
代码通过java编译成class文件再通过javac放入内存的JVM中,在JVM中存在方法区,程序放入方法区中等待进一步编译。
main方法入栈后在堆里的变量只有name和age,没有from。
from变量实际上存放在方法区中,更确切的说法是它存在于类中,被zhangsan和lisi一起共享,zhangsan和lisi进行修改的时候都是修改了类里的from变量,而不是各自对象内部的变量。
在方法区中,存在一块空间叫做静态常量池,我们的from变量就放在了静态常量池中。
static可以修饰的范围
变量
static修饰的变量属于类变量,被创建出来的所有对象共享。
方法
static修饰的变量属于类,叫做静态方法,没有被static修饰的方法属于对象。
在静态方法中不能调用非静态的方法。因为静态方法属于当前这个类,类去构建对象,但是有类不一定有对象,在类加载的时候静态方法就已经被加载了,而此时非静态的方法还没有被加载,因此静态方法无法调用非静态方法。
而非静态方法可以调用静态方法,因为非静态方法加载的时候静态方法已经被加载了,因此可以进行调用。
public class Person{
private String name;
private int age;
private static String from;
public static void main(String[]args){
Person zhangsan = new Person;
zhangsan.age = 18;
zhangsan.name = "zhangsan";
zhangsan.from = "China";
Person lisi = new Person;
lisi.age = 20;
lisi.name = "lisi";
lisi.from = "USA";
System.out.println(zhangsan.name + " " + zhangsan.age + " " +zhangsan.from);
System.out.println(lisi.name + " " + lisi.age + " " +lisi.from);
run(); //可以被调用
name(); //无法被调用
}
public static void run(){
}
public void name(){
run(); //可以被调用
}
}
代码块
凡是在 { } 内部的都是代码块,代码块表示一个范围,在代码块内部创建的变量叫做局部变量,无法在代码块外调用。
static修饰的代码块同样表示一个范围,static修饰的代码块内的变量同样无法在代码块之外进行访问,但是被static修饰的代码块无论放在哪里都会比main方法更优先执行。可以用于优化程序。
public class Person{
static {
System.out.println("我是static修饰的");
}
{
System.out.println("");
}
public static void main(String[]args]){
System.out.println("");
}
static{
System.out.println("");
}
{
System.out.println("");
}
}