一,static关键字的用途
方便在没有创建对象的情况下来进行调用(方法/变量)。
被static关键字修饰的方法或者变量,不需要依赖于对象来进行访问,只要类被加载了。
可以通过类名去访问。
可以修饰 类的成员方法,成员变量,static 代码块
1.static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类
的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
package com.xiaoqiang.test;
public class BaseTest {
private static String str = "www.baidu.com";
private String str2 = "www.qidian.com";
public static void print() {
System.out.println(str);
System.out.println(str2);
}
}
禁止在静态成员方法中访问非静态成员方法。
因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何
对象,因此只有通过类名来访问。
2.static变量
static变量也称作静态变量,静态变量和非静态变量的区别:
静态变量被所有的对象共享,在内存中只有一个副本,
它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
3.static块
可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
所以用来优化程序。
package com.xiaoqiang.test;
import java.sql.Date;
public class Women {
private Date birthDate;
public Women(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
Date startDate = Date.valueOf("1946-12-11");
Date endDate = Date.valueOf("1946-11-11");
return birthDate.compareTo(startDate) >= 0 && birthDate.compareTo(endDate) < 0;
}
}
isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:
package com.xiaoqiang.test;
import java.sql.Date;
public class Car {
private Date birthDate;
private static Date startDate, endDate;
public Car(Date birthDate) {
this.birthDate = birthDate;
}
static {
startDate = Date.valueOf("1946-12-11");
endDate = Date.valueOf("1946-11-11");
}
boolean isBornBoomer() {
return birthDate.compareTo(startDate) >= 0 && birthDate.compareTo(endDate) < 0;
}
}
这样一改,第一次初始化就处理了.
4.static关键词修饰类
static修饰内部类,普通类是不允许声明为静态的,
只有内部类才可以。
被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类
需要注意的是当一个内部类没有使用static修饰的时候,是不能直接使用内部类创建对象,须要先使用外部类对象点new内部类对象及(外部类对象.new 内部类())
package com.xiaoqiang.test;
public class OutXxq {
public static void main(String[] args) {
OutXxq outXxq = new OutXxq();
InnerXxq innerXxq = outXxq.new InnerXxq();
}
class InnerXxq {
public InnerXxq() {
System.out.println("我是内部类");
}
}
}
这是不用静态类 初始化方式
只是用静态类初始化:
package com.xiaoqiang.test;
import com.xiaoqiang.test.OutXxq.InnerXxq;
public class OutXxq {
public static void main(String[] args) {
OutXxq.InnerXxqs b = new OutXxq.InnerXxqs();
}
class InnerXxq {
public InnerXxq() {
System.out.println("我是内部类");
}
}
static class InnerXxqs {
public InnerXxqs() {
System.out.println("我静态内部类");
}
}
}
二.static关键字的误区
1.static关键字会改变类中成员的访问权限吗?
不会
2.能通过this访问静态成员变量吗?
package com.xiaoqiang.test;
public class BaseTest {
private static String str = "www.baidu.com";
private String str2 = "www.qidian.com";
static int a = 44;
public static void print() {
System.out.println(str);
}
private void testA() {
int a = 5;
System.out.println(this.a);
}
public static void main(String[] args) {
new BaseTest().testA();
}
}
打印:44
this代表什么?this是当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。
而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是44。
在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是44。
静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
3.static能作用于局部变量么?
static是不允许用来修饰局部变量
三.常见的笔试面试题
package com.xiaoqiang.test;
public class Dog extends Animal {
static {
System.out.println("test static");
}
public Dog() {
System.out.println("test constructor");
}
public static void main(String[] args) {
new Dog();
}
}
class Animal {
static {
System.out.println("base static");
}
public Animal() {
System.out.println("base constructor");
}
}
输出的结果是:
base static
test static
base constructor
test constructor
这段代码具体的执行过程:
在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Test类,而在加载Test类的时候发现Test类继承自Base类,因此会转去先加载Base类,在加载Base类的时候,发现有static块,
便执行了static块。在Base类加载完成之后,便继续加载Test类,然后发现Test类中也有static块,便执行static块。在加载完所需的类之后,便开始执行main方法。在main方法中执行new Test()的时候会先调用父类的构造器,然后
再调用自身的构造器。
public class Test {
static{
System.out.println("test static 1");
}
public static void main(String[] args) {
}
static{
System.out.println("test static 2");
}
}
test static 1
test static 2
虽然在main方法中没有任何语句,但是还是会输出,原因上面已经讲述过了。另外,static块可以出现类中的任何地方(只要不是方法内部,记住,任何方法内部都不行),并且执行是按照static块的顺序执行的。
参考资料:
https://www.cnblogs.com/dolphin0520/p/3799052.html