Java虚拟机的内存分区:Java栈、堆、方法区、本地方法栈、PC寄存器。还有一个常量池的概念,虚拟机会为每种类型分配一个常量池,而不是实例。

例如有一个类有很多子类,那么在父类定义的final变量,在子类是不能被改变的。可以说明是在类型上分配的。

被static修饰的变量或者方法是属于类本身,而不属于类的实例。在类被加载进虚拟机的时候就已经初始化了,他存在与方法区,方法区和堆区的时候是共享的,因此他被设计为线程安全的。假设同时有两个线程都企图访问一个名为A的类,而这个类还没有被转入虚拟机,此时只应该有一个线程去装载它,而另一个线程只能等着。所以为什么我们可以说static定义的变量是共享数据。

我们举两个例子看下他们的不同。

public interface Angry {
String greeting = "Girl!!!"; int angryLevel = Dog.getAngryLevel();
}
public class Dog {

    static final String greeting = "Woof,woof";

    public Dog() {
System.out.println("DOg");
} static{ System.out.println("Dog is in");
} static int getAngryLevel(){
System.out.println("Angry is in");
return 1;
}
}
public class Example1 {

    public static void main(String[] args) {
System.out.println(Angry.greeting);
System.out.println(Dog.greeting);
//new Dog(); }
static {
System.out.println("Exampl1");
}
}

这个的输出结果是:

Exampl1
Girl!!!
Woof,woof

把new Dog();注释的代码打开,在看看结果。

Exampl1
Girl!!!
Woof,woof
Dog is in
DOg

再来看看下面的代码:

public class A{
static int a = 10; static{
System.out.println("初始化A");
}
}
public class B extends A{
static int b = 5; static{
System.out.println("初始化B");
}
}
public class Example2{

    public static void main(String[] args){

        int c = B.b;
System.out.println(c);
} static{
System.out.println("初始化Example2");
}
}

他的输出结果是:

初始化Example1

初始化A

5

开始我一直以为调用到了这个类的方法或者变量的时候,就会执行静态代码块或者是非静态代码块。看了《深入java虚拟机》之后明白了很多。

总结下:

第一个例子:3个类都没有继承关系。接口定义的变量默认是public static final的,方法默认是public abstract。

main方法是程序的入口,虚拟机会初始化该线程所在的类,那么他会先执行静态代码块的内容,然后程序再从上往下执行,执行Angry.greeting,打印他的值,执行Dog.greeting,打印他的值。Angry和Dog都没有实例化。所以不会调用静态代码块的方法。

new 一个Dog对象,此时程序主动实例化一个对象,那么他会调用Dog的静态代码块、非静态代码块、无参构造函数。

第二个例子:B类继承了A类。在Example2中也没有主动的创建B类对象,但是程序调用了B类的静态变量,而B类又继承了A类,虚拟机会先加载并实例化A类(B的父类),所以会执行A类的静态代码块、非静态代码块、无参构造函数。

但是他却没有执行B类的静态代码块,因为程序没有主动的实例化B类对象。

有六种情形属于主动使用初始化。

1、当创建某个类的新实例时(new、克隆、反序列化、反射)

2、调用静态方法。

3、使用到某个类或接口的静态字段,或者对该字段赋值,用final修饰的静态字段除外,他被初始化为一个编译时的常量表达式。

4、当初始化某个类的子类时。

5、使用某个类的Class中的反射方法时。

6、启动有main方法的类。

java代码块 静态、非静态的更多相关文章

  1. JAVA程序执行顺序(静态代码块》非静态代码块》静态方法》构造函数)

    总结:静态代码块总是最先执行. 非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行. 父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非 ...

  2. java中静态代码块,非静态代码块,构造函数

    关于静态代码块 静态代码块的写法: static { System.out.println("我是静态代码块"); } 静态代码块的特点: 1.执行优先级高于非静态的初始化块,它会 ...

  3. Java中静态变量、静态代码块、非静态代码块以及静态方法的加载顺序

    在研究单例设计模式的时候,用到了静态变量和静态方法的内容,出于兴趣,这里简单了解一下这四个模块在类初始化的时候的加载顺序. 经过研究发现,它们的加载顺序为: 1.非静态代码块 2.静态变量或者静态代码 ...

  4. Java子父类间静态代码块、非静态代码块、构造方法的执行顺序

    子类A继承父类B,A a=new A(); 正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A ...

  5. Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...

  6. Java静态代码块与非静态代码块

    静态代码块,格式是 static{ },随着类的加载而加载,且只执行一次. 在程序中,执行的优先级最高. 非静态代码块,格式是{ },在创建对象的时候运行(即new一个对象的时候),每创建一次对象就执 ...

  7. 浅谈Java中静态代码块和非静态代码块

    静态代码块: static{} 执行优先级高于非静态的初始化块,它会在类初始化(类初始化这个问题改天再详细讨论)的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员. 非静 ...

  8. java基础-静态,非静态(构造)代码块,类加载

    static block and non-static block(constructor block) [toc] 想来想去,先来一题比较好 public class Foo { public st ...

  9. Java 代码块

    一.简介 1.普通代码块: 类中方法的方法体 2.构造代码块: 构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行. 3.静态代码块: 用static{}包裹起来的代码片段,只会执 ...

随机推荐

  1. 【JAVA】类继承对父类静态变量的操作

    对静态变量的操作存在继承时还是有一些模糊,做了个简单的测试: class Test { private String mName; public Test(String name) { setName ...

  2. CodeForces 669C Little Artem and Matrix GNU

    模拟. 把操作记录一下,倒着复原回去. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cs ...

  3. 【锋利的Jquery】读书笔记一

    封面镇楼: 读这本书应该是7月份,二周读完,经典的好书,一直没怎么复习.so....温故而知新下. 一.jquery的风格 链式风格 <div class="box"> ...

  4. 关于Trie Tree简单实现

    最近突然有兴致hiho一下了,实现了下trie tree,感觉而言,还是挺有意思的,个人觉得这货不光可以用来查单词吧,其实也可以用来替代Hash,反正查找,插入复杂度都挺低的,哈哈,啥都不懂,瞎扯.. ...

  5. C# 语言规范_版本5.0 (第6章 转换)

    1. 转换 转换(conversion) 使表达式可以被视为一种特定类型.转换可导致将给定类型的表达式视为具有不同的类型,或其可导致没有类型的表达式获得一种类型.转换可以是隐式的 (implicit) ...

  6. jquery中的serialize

    jquery中的serialize对serializeArray进行了封装,serializeArray源码中定义将disabled的过滤掉,所以提交后值为null 解决方式是:在提交的时候,讲dis ...

  7. SURF 特征法

    public static void FindMatch(Mat modelImage, Mat observedImage, out long matchTime, out VectorOfKeyP ...

  8. iOS Plugins

    iOS Plugins This section provides details for how to implement native plugin code on the iOS platfor ...

  9. JavaScript-Curry

    Currying allows you to easily create custom functions by partially invoking an existing function. He ...

  10. 阿里云-对象储存OSS

    最近 需要搞一个阿里云的文件上传 手机端主要做了图片上传 pod安装:pod 'AliyunOSSiOS', '~> 2.5.2' 主要就是需要四个参数:accessKey secretKey  ...