首先我们来搞清楚java中的静态属性和静态方法。
有关静态常见的问题
这里我问几个问题,供大家思考一下,看看自己是否可以秒答。
- 1.静态属性可以被继承吗?
- 2.静态方法可以访问非静态属性吗?
- 3.非静态方法可以访问静态属性吗?
- 4.静态方法中可以使用this/super关键字吗?
- 5.为什么静态方法不能调用非静态方法或者变量呢?
- 6.静态属性、非静态属性、静态代码块、非静态代码块、构造函数在初始化时的执行顺序是怎样的?
先说答案:
- 1.可以,继承跟是否静态无关,只跟作用域有关(private public protected)
- 2.不可以,同4
- 3.可以,因为静态变量是存储在静态内存单元内,可以直接用类进行调用,也可以用实例化的对象对其引用。所以非静态方法是可以引用静态变量的
- 4.不可以,this指代当前对象的引用,super指代父类对象的引用,静态方法属于类,不属于某一个对象,当静态方法加载的时候,对象还不一定存在。如果静态方法中有this和super那么当静态方法被加载到内存中,其中的this和super也被加载到内存中,但是对象还没创建this和super还没被初始化,所以加载时会报错。
- 5.静态方法是属于类的,不需要实例化,不是属于对象的,而非静态变量是属于对象的,需要先实例化。在一个类的静态方法中访问非静态成员,之所以出错是因为,在类的非静态成员不存在的时候,类的静态属性已经存在了,访问一个内存中不存在的东西当然会报错。
- 6.不考虑继承关系的话,静态属性和代码块(按照代码出现的顺序)>非静态属性和非静态代码块>构造函数
马上来验证一下
public class StaticDemo {
public String b = "非静态属性";
public static String a = "静态属性";
static {
System.out.println(a);
System.out.println("静态代码块");
}
{
System.out.println(b);
System.out.println("非静态代码块");
}
public StaticDemo() {
System.out.println("构造函数");
}
public static void main(String[] args) {
StaticDemo demo = new StaticDemo();
}
}
复制代码
打印结果:
静态属性
静态代码块
非静态属性
非静态代码块
构造函数
复制代码
在有继承关系的情况下
父类的静态属性和静态代码块>子类的静态属性和静态代码块>父类的非静态属性>父类的构造函数>子类的非静态函数>子类的构造函数
再来验证一下
class ParentClass{
public static String pA = "父类-静态属性";
public String pB = "父类-非静态属性";
static {
System.out.println(pA);
System.out.println("父类-静态代码块");
}
{
System.out.println(pB);
System.out.println("父类-非静态代码块");
}
public ParentClass() {
System.out.println("父类-构造函数");
}
}
public class StaticDemo extends ParentClass{
public String b = "非静态属性";
public static String a = "静态属性";
static {
System.out.println(a);
System.out.println("静态代码块");
}
{
System.out.println(b);
System.out.println("非静态代码块");
}
public StaticDemo() {
System.out.println("构造函数");
}
public static void main(String[] args) {
StaticDemo demo = new StaticDemo();
}
}
复制代码
执行结果:
父类-静态属性
父类-静态代码块
静态属性
静态代码块
父类-非静态属性
父类-非静态代码块
父类-构造函数
非静态属性
非静态代码块
构造函数
复制代码
这几个问题我们知道答案了,但是为什么会产生这样的结果呢?
类是如何加载的
我们看一下类的加载过程:
喜欢就支持一下吧
相关推荐