——static
static关键字是很多同学在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一。
static修饰符可以用来修饰类的成员变量、成员方法和代码块。
用static修饰的成员变量表示静态变量,可以直接通过类名来访问;
用static修饰的成员方法表示静态方法,可以直接通过类名来访问;
用static修饰的程序代码表示静态代码块,当Java虚似机加载类时,就会执行该代码块。
被static所修饰的成员变量和成员方法表明归某个类所有,它不依赖于类的特定实例,被类的所有实例共享。
——static变量(静态变量)
形式和实例变量类似,在实例变量前面加static关键字;
——static变量和实例变量的区别:
static变量对于每个类而言在内存中只有一个,能被类的所有实例所共享;实例变量对于每个类的每个实例都有一份,它们之间互不影响;
Java虚拟机在加载类的过程中为static变量分配内存,实例变量在加载完类后创建对象时分配内存;
static变量可以直接通过类名访问,实例变量通过引用类型变量访问;
Q1:下面程序运行完毕后,count1、count2对应的值是多少。
public class Counter {
public int count1 = 0;
public static int count2 = 0;
public static void main(String[] args) {
CountercounterA = new Counter();
CountercounterB = new Counter();
counterA.count1++;
counterA.count2++;
counterB.count1++;
counterB.count2++;
}
}
练习:统计一个类创建实例的个数;
——总结:
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
——static方法(静态方法)
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
另外记住,即使没有显示地声明为static,类的构造器实际上也是静态方法。
——static方法注意事项:
1、不能使用this关键字;
this代表什么?this代表当前对象,但是对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。
2、不能使用super关键字;
super关键字用来访问当前实例从父类中继承的方法和属性。super关键字与类的特定实例相关;
3、静态方法必须被实现;
静态方法用来表示某个类所特有的功能,这种功能的实现不依赖于类的具体实例,也不依赖于它的子类。既然如此,当前类必须为静态方法提供实现。
4、父类的静态方法不能被子类覆为非静态方法;
5、父类的非静态方法不能被子类覆盖为静态方法;
——static代码块(静态代码块)
static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
构造代码块:
在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
Q1:static关键字会改变类中成员的访问权限吗?
Q3:为什么main方法要加static修饰
[1]
——静态导入
静态导入也是JDK5.0引入的新特性。
要使用静态成员(方法和变量)我们必须给出提供这个静态成员的类。使用静态导入可以使被导入类的静态变量和静态方法在当前类中可以直接使用,使用这些静态成员无需再在前面写上他们所属的类名。
java都是以类作为程序的组织单元,当我们要执行的时候,我们并不知道这个main方法会放到哪个类当中,也不知道是否是要产生类的一个对象,为了解决程序的运行问题,我们将这个main方法定义为static,这样的话,当我们在执行一个java代码的时候,我们在命令提示符中写:java Point(Point为一个类),解释器就会在Point这个类当中,去调用这个静态的main方法,而不需要产生Point这个类的对象,当我们加载Point这个类的时候,那么main方法也被加载了,作为我们java程序的一个入口。
public被jvm调用,访问权限足够大。
static被jvm调用,不用创建对象,直接类名访问
void被jvm调用,不需要给jvm返回值
main一个通用的名称,虽然不是关键字,但是被jvm识别
String[]args 以前用于接收键盘录入的