static 静态
static可以修饰:属性,方法,代码段,内部类(静态内部类或嵌套内部类),静态接口方法(Java8以上支持)
静态让使用和运行的便捷,不需要实例化,相当于直接使用,增加了公共代码复用的便捷性。
static和“this、super”势不两立,static跟具体对象无关,而this、super正好跟具体对象有关。
静态变量
属性被声明成静态属性(类属性),则表示属性的值被所有的对象共享,所有程序对它的引用都会指向这一个地址而不会重新分配内存。
public class Test {
// 静态变量
public static int age1 = 0;
// 实例变量
public int age2 = 0;
public Test() {
age1++;
age2++;
System.out.println("age1=" + age1 + "," + "age2=" + age2);
}
public static void main(String[] args) {
// age1=1,age2=1
Test t1 = new Test();
// age1=2,age2=1
Test t2 = new Test();
}
}
而实例变量属于某个对象的属性,必须创建了实例对象,实例变量才被分配空间,才能使用这个实例变量。
静态变量属于类,不需要创建实例对象,静态变量就会被分配空间,就可以被使用。
但是static不可以修饰局部变量。
静态方法
与静态变量一样,静态方法是属于类而不是实例。
一个静态方法只能使用静态变量和调用静态方法。可以使用类名.方法名的方式来访问。
public class Test {
public static void main(String[] args) {
MyStatic.show();
}
}
class MyStatic{
public static void show(){
System.out.println("mystatic");
}
}
Java的包装类和实用类包含许多静态方法。main()方法就是Java程序入口点,是静态方法。
静态方法只能继承,不能重写。
public class Test {
public static void main(String[] args) {
Father f=new Son();
f.show();
}
class Father{
public static void show(){
System.out.println("父类");
}
}
class Son extends Father{
public static void show(){
System.out.println("子类");
}
}
输出结果为"父类"
不能在静态方法中访问非静态的成员变量,但可以在非静态方法中访问静态的成员变量。
静态块
Java不允许在静态块中使用非静态变量。一个类中可以有多个静态块。
类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会加载一个,所以静态代码块也只会被执行一次。
而构造方法每次生成一个对象的时候,都会调用类的构造方法,所以new一次就会调用构造方法一次。
当继承中有构造方法,也有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层的构造方法。
public class Test {
public static void main(String[] args) {
new C();
new C();
}
}
class A{
//static静态代码块
static {
System.out.println("static block");
}
public A(){
System.out.println("A");
}
}
class B extends A{
static {
System.out.println("static block");
}
public B(){
System.out.println("B");
}
}
class C extends B{
static {
System.out.println("static block");
}
public C(){
System.out.println("C");
}
}
输出结果:
static block
static block
static block
A
B
C
A
B
C
final
final可以修饰:属性,方法,类,局部变量(方法中的变量)
final修饰属性
final修饰的属性表明是一个常数(创建后不能被修改)。
属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变。
public class Test {
public static void main(String[] args) {
finalTest f=new finalTest();
f.age=9;//报错
}
class finalTest{
final int age=10;
}
对于final类型成员变量,一般来说有两种赋值方式:
- 在声明final类型的成员变量时就赋初值
- 在声明final类型的成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值。
public class FinalTest {
final int a;
public FinalTest() {
a = 0;
}
public FinalTest(int a) {
this.a = a;
}
}
如果final修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。
public class Test {
public static void main(String[] args) {
finalTest f=new finalTest();
f.t.name="o";//编译成功
}
class finalTest{
final finalTest2 t=new finalTest2();
}
class finalTest2{
String name="j";
}
final修饰方法
方法被final所修饰的时,表示该方法是一个终态方法,不能被重写。修饰的类表示该类不能被继承。
public class Test {
public static void main(String[] args) {
finalTest2 f=new finalTest2();
f.show();
}
class finalTest{
public final void show(){
System.out.println("show1");
}
}
class finalTest2 extends finalTest{
public void show(){//报错
System.out.println("show2");
}
}
static final
static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。static final修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问。
static final也可以修饰方法,表示该方法不能重写,可以在不new对象的情况下调用。
static final和final static没什么区别,一般static写在前面。