所谓非静态看对象
静态看类
只要类存在,静态的变量就存在了,不像非静态变量需要建立对象调用
四种用法
成员方法
成员变量
静态块
静态导包
注意:
1.不可以修饰类(除了内部类,这个我们下面再了解)
2.不可以修饰局部变量
1.修饰成员变量
public class Person {
String name;
int age;
public String toString() {
return "Name:" + name + ", Age:" + age;
}
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "zhangsan";
p1.age = 10;
Person p2 = new Person();
p2.name = "lisi";
p2.age = 12;
System.out.println(p1);
System.out.println(p2);
}
}
可以看出非静态用要先创建对象再调用
根据Person构造出的每一个对象都是独立存在的,保存有自己独立的成员变量,相互不会影响。
而如果改成
static String name;
可以看出此时的年龄都是12
因为此时的age是属于整个类的
Person对象就不再拥有age属性了,age属性会统一交给Person类去管理,即多个Person对象只会对应一个age属性,一个对象如果对age属性做了改变,其他的对象都会受到影响。我们看到此时的age和toString()方法一样,都是交由类去管理。
2.修饰成员方法
static的另一个作用,就是修饰成员方法。相比于修饰成员属性,修饰成员方法对于数据的存储上面并没有多大的变化,因为我们从上面可以看出,方法本来就是存放在类的定义当中的。static修饰成员方法最大的作用,就是可以使用"类名.方法名"的方式操作方法,避免了先要new出对象的繁琐和资源消耗。
//先展示同一个类下面的
public class PrintHelper {
public static void print(Object o){
System.out.println(o);
}
public static void main(String[] args) {
PrintHelper.print("Hello world");//String是Object的子类
//同类下面可以不写类名字直接调用
}
}
//这个展示调用不同java文件的类和一个java文件的两个类
//其实大同小异,主要是不同java文件需要先导入,如果本来在一个类可以不用导入,直接类名.方法名
package com.hansp.Encop;
import com.kuangshen.Demo02;//这里导入Demo02的类
public class Demo01 {
public static void main(String[] args) {
Person person = new Person();//
Demo02.show();//调用不同类的方法
Person.getSalary();//调用同一个java文件下的其他类的static方法
}
}
class Person{
private static double salary;
public static double getSalary() {
return salary;
}
这里可以看见啊,我只能调用Person.里面的getSalary方法,其实里面还有其他方法不过不是static的
可以说明,类名.方法名这种方法只可以调用静态的(当然这是在不同的类下)
如果在同一个类直接掉加行
非static方法必须先new对象然后通过对象名.方法调用
当然修饰成员方法的内部不允许出现类似this和super关键字
因为这些关键字是和对象绑定的而static是和类绑定的
3.静态块
package com.dotgua.study;
class Book{
public Book(String msg) {
System.out.println(msg);
}
}
public class Person {
Book book1 = new Book("book1成员变量初始化");
static Book book2 = new Book("static成员book2成员变量初始化");
public Person(String msg) {
System.out.println(msg);
}
Book book3 = new Book("book3成员变量初始化");
static Book book4 = new Book("static成员book4成员变量初始化");
public static void main(String[] args) {
Person p1 = new Person("p1初始化");
}
/**Output
* static成员book2成员变量初始化
* static成员book4成员变量初始化
* book1成员变量初始化
* book3成员变量初始化
* p1初始化
*///~
}
上面的例子中,Person类中组合了四个Book成员变量,两个是普通成员,两个是static修饰的类成员。我们可以看到,当我们new一个Person对象时,static修饰的成员变量首先被初始化,随后是普通成员,最后调用Person类的构造方法完成初始化。也就是说,在创建对象时,static修饰的成员会首先被初始化,而且我们还可以看到,如果有多个static修饰的成员,那么会按照他们的先后位置进行初始化。
当我们使用了类方法,完成类的成员的初始化后,再new该类的对象时,static修饰的类成员没有再次初始化,这说明,static修饰的类成员,在程序运行过程中,只需要初始化一次即可,不会进行多次的初始化。
4.静态导包
而在App.java文件中,我们首先将Math类导入,这里在导入时,我们使用了static关键字,此时我们后面加个radonm就可以用用Math里的random方法。不同于非static导入,采用static导入包后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法了,直接可以采用"方法名"去调用类方法,就好像是该类自己的方法一样使用即可。
可以
import static java.lang.Math.*;
相当于导入了Math里面的所有方法
5.内部类
class Person
编程内部类以后就不能在main方法直接new了
要先static class Person
因为现在他们属于同一个类
会先加载main方法,但是在static的main里面调用本类别的非static就会报错
总结
static是java中非常重要的一个关键字,而且它的用法也很丰富,主要有四种用法:
- 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
- 用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
- 静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键;
- 静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。