学习关键字static、final
在学习的过程中经常会看见两个关键字:static和final。虽然基本都知道这两个关键字的用法和意义,但是有时候总会想不起来,当你想起来的时候可能问题已经用别的方式处理了。这里来记录一下
static
1、static修饰变量
// 在类Test声明一个静态变量 i = 123
public class Test {
public static int i =123;
public static void main(String[] args) {
//输出i
System.out.println(“i=”+Test.i);
}
}
结果:
i=123
注:这里输出i的时候使用的是 类名.变量名 的方式。访问方法时也可使用 类名.方法名
这里可以看到我们的main方法是经过static修饰的方法,静态方法可以调用静态变量,那么非静态方法可以调用静态变量吗?
public class Test {
// 在类Test声明一个静态变量 i = 123
public static int i =123;
public void testFun(){
//输出i
System.out.println("i="+Test.i);
}
public static void main(String[] args) {
//创建对象
Test test =new Test();
//执行test中的testFun()方法
test.testFun();
}
}
结果:
i=123
上面结果可以看到,非静态方法也是可以访问静态变量的。那么静态方法能访问非静态变量吗?
public class Test {
//声明一个非静态变量s=321
public int s = 321;
public static void main(String[] args) {
System.out.println("s="+s);
}
}
结果:
报错: Non-static field ‘s’ cannot be referenced from a static context
这就说明了在静态方法中不能访问非静态变量,同样的静态方法不能直接调用非静态变量。
为什么呢?
从jvm的类加载机制上来说。静态内容是类的初始化的时候进行的,非静态内容是在new对象的时候进行的。而初始化始终是在new之前完成,所以在初始化的时候并不认识new时候的内容。
打个比方(可能不是很恰当):在父亲那一年代就相当于类的初始化(执行static内容),并不知道自己有孩子、也不知道孩子叫什么、不知道孩子有什么行为。 但是在孩子那个年代就相当于new,孩子却知道有父亲、知道父亲叫什么、知道父亲有什么行为。
2、静态块
一个静态块的例子
public class TestA {
static
{
System.out.println("A的静态块");
}
public TestA()
{
System.out.println("A的构造方法");
}
}
public class TestB extends TestA {
static
{
System.out.println("B的静态块");
}
public TestB()
{
System.out.println("B的构造方法");
}
public static void main(String[] args) {
new TestB();
new TestB();
}
}
结果
A的静态块
B的静态块
A的构造方法
B的构造方法
A的构造方法
B的构造方法
从结果可以看出,静态块的代码的顺序是 父类静态块>子类静态块 ,并且静态块的内容只执行一次。
final
当说起这个关键字的时候,都会想起三点
1、被final修饰的类不可以被继承
2、被final修饰的方法不可以被重写
3、被final修饰的变量不可以被改变
//final 修饰类
public final class TestA {
}
//继承被final修饰的类
public class TestB extends TestA {
}
结果:这里会报错 Cannot inherit from final 'com.framework.loippi.utils.TestA 不能继承被final修饰的类
//继承被final修饰的类
public final class TestA {
public final static String str = "hello";
public static void main(String[] args) {
str="asdf";
System.out.println(str);
}
}
结果:这里会报错 Cannot assign a value to final variable 'str '。 不能修改被final修饰的变量