1、static解释
static是一个用于修饰类的成员变量和方法的关键字。它表示该成员变量或方法属于类本身,而不是类的实例。
2、static修饰的方法
static修饰的方法叫做静态方法。成员方法的在其它类中的调用通过实例调用,静态方法调用通过类名直接调用。
代码:
创建一个类AAA,类中有两个方法,aT方法通过static修饰属于静态方法,aC方法属于成员方法。
public class AAA {
public static String aT(){
System.out.println("调用");
return "ss";
}
public String aC(){
System.out.println("调用");
return "sa";
}
}
创建一个类实BBB现对AAA中方法进行调用
import xx.xx.xx.xx.AAA
public class BBB {
public static void main(String[] args) {
//调用aT静态方法
System.out.println(AAA.aT());
//调用aC成员方法,需要实例进行调用
AAA t=new AAA();
System.out.println(t.aC());
}
}
3、static修饰的变量
static修饰的变量叫做静态变量。成员变量的在其它类中的调用通过实例调用,静态变量调用通过类名直接调用。
代码:
创建一个类AAA,类中有两个变量,a变量通过static修饰属于静态变量,aC方法属于成员变量。
public class AAA {
public static int a="a";
public int b="b";
}
创建一个类实BBB现对AAA中变量进行调用
import xx.xx.xx.xx.AAA
public class BBB {
public static void main(String[] args) {
//调用a静态变量
System.out.println(AAA.a);
//调用b成员变量,需要实例进行调用
AAA t=new AAA();
System.out.println(t.b);
}
}
4、静态static代码块
4类代码块:静态初始化代码块、实例化初始代码块(构造代码块)、构造函数(构造方法)、普通方法体
public class Aaa {
//实例化初始代码块(构造代码块)
{
System.out.println("构造代码块");
}
//静态代码块
static {
System.out.println("静态代码块");
}
//构造方法
public Aaa() {
System.out.println("构造方法");
}
//普通方法
public void ss() {
System.out.println("普通方法");
}
}
输出
静态代码块
构造代码块
构造方法
普通方法
他们的执行顺序为:静态初始化代码块、实例化初始代码块(构造代码块)、构造函数(构造方法)、普通方法体
5、static修饰内部类
静态内部类:静态内部类是定义在一个类中的类,用static关键字修饰
静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法;
静态内部类中即能声明静态成员也可以声明非静态成员。
public class Static {
static String name = "外部类的类名";
//静态内部类中不能访问外部类非静态成员
String type = "外部类的type属性";
public static class Inner{
//四种权限修饰符可以修饰静态内部类
public String name = "静态内部类的类名";
static double weight = 1.8;
String type = "静态内部类的type属性";
public void show(){
System.out.println("我是:" + weight);
System.out.println("我是:" + type);
System.out.println("我是:" + name);
//System.out.println("我是:" + Static.type);//静态内部类中不能访问外部类非静态成员
System.out.println("我是:" + Static.name);
}
}
public static void main(String[] args) {
//静态内部类可以直接实例化 不需要依附于外部类
Inner inner = new Inner();
inner.show();
}
}
6、static导包
静态导包使用static关键字,而且在引入类的最后还加上了“.*”,它的作用就是将导入类的中的所有类方法直接导入。不同于非static导入,采用static导入包后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法了,直接可以采用"方法名"去调用类方法,就好像是该类自己的方法一样使用即可。
public class TestA3 {
public void aa(){
System.out.println("调用");
}
}
//静态导包
import static xx.xx.xx.TestA3.*;
public class TestA1 {
public void bb(){
//可以直接调用TestA3中的aa方法
System.out.println(aa());
}
}
7、static与非static的区别(内存)
前文已知非static方法与变量属于类的实例,实例化后的对象(实例)一般存储在JVM的堆里,所以非静态的变量与属性都存放在堆里。
而static修饰的属性和方法存放在方法区里。
非static方法与变量在对象(实例)消失时消失,在JVM中对象(实例)存放在堆中,在一次次GC(回收)中存活,static方法与变量在类消失时消失,JVM中方法区是存放永久代的区域,在方法区里的方法与变量生命周期一般来讲较堆中的对象长。
8、静态方法不能不能调用非静态方法与属性
原理关于到类的加载过程,类加载过程中,会加载静态属性方法/属性/代码块,而非静态的属性方法代码块,只有这个类被实例化后才会开始加载,分配内存。