java代码块 静态、非静态
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代码块 静态、非静态的更多相关文章
- JAVA程序执行顺序(静态代码块》非静态代码块》静态方法》构造函数)
总结:静态代码块总是最先执行. 非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行. 父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非 ...
- java中静态代码块,非静态代码块,构造函数
关于静态代码块 静态代码块的写法: static { System.out.println("我是静态代码块"); } 静态代码块的特点: 1.执行优先级高于非静态的初始化块,它会 ...
- Java中静态变量、静态代码块、非静态代码块以及静态方法的加载顺序
在研究单例设计模式的时候,用到了静态变量和静态方法的内容,出于兴趣,这里简单了解一下这四个模块在类初始化的时候的加载顺序. 经过研究发现,它们的加载顺序为: 1.非静态代码块 2.静态变量或者静态代码 ...
- Java子父类间静态代码块、非静态代码块、构造方法的执行顺序
子类A继承父类B,A a=new A(); 正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A ...
- Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...
- Java静态代码块与非静态代码块
静态代码块,格式是 static{ },随着类的加载而加载,且只执行一次. 在程序中,执行的优先级最高. 非静态代码块,格式是{ },在创建对象的时候运行(即new一个对象的时候),每创建一次对象就执 ...
- 浅谈Java中静态代码块和非静态代码块
静态代码块: static{} 执行优先级高于非静态的初始化块,它会在类初始化(类初始化这个问题改天再详细讨论)的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员. 非静 ...
- java基础-静态,非静态(构造)代码块,类加载
static block and non-static block(constructor block) [toc] 想来想去,先来一题比较好 public class Foo { public st ...
- Java 代码块
一.简介 1.普通代码块: 类中方法的方法体 2.构造代码块: 构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行. 3.静态代码块: 用static{}包裹起来的代码片段,只会执 ...
随机推荐
- idea空包自动叠加问题
取消上面选项就行了.
- 遍历json创建树状表(首先的前提条件是要引入jquery的jquery treeTable插件)
"root":{ "children":[ { "name":"AA", "children":[ ...
- app兼容性测试的几种方案
1.统计自己的应用被使用的数据 通过友盟或Flurry等在应用嵌入,得到应用在哪些机型上被安装了,排名前十的就是测试的重点机型 2.可参考兼容性测试平台的测试结果 比如Testin或百度的MTC平台, ...
- Unity3DGUI:鼠标click
Input函数监测鼠标操作 鼠标点击事件 鼠标双击事件
- 字串变换 (2002 年NOIP全国联赛提高组)
一道看似非常水的题 大意 :将一个字串 经过几种变换规则变为给定的另一个子串 ,求最小操作数. code[vs] 传送门 洛谷传送门 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): ...
- [WPF] 为Style 里的button添加鼠标点击响应事件
一个TabControl, 用的是PagedTabControl style, 在style中有个button, button在style里已经写了click事件,但是现在还需要加上一段功能,就是在响 ...
- MySQL字段联合去重sql
MySQL字段联合去重sql 例如数据 id,name1,name2 1 a x 2 a y 3 b x 4 a y 5 a x 联合去重name1,name2的结果为 id,name1,name2 ...
- C++设计模式-singleton单例模式_new
class nocopyable { protected: nocopyable(){}; virtual ~nocopyable(){}; nocopyable(const nocopyable ...
- 小谈数据库Char、VarChar、NVarChar差异
1. char 固定长度,最长n个字符. 2. varchar 最大长度为n的可变字符串. (n为某一整数,不同数据库,最大长度n不同) char和varchar区别: ...
- Webpack学习笔记(二)
市面上已经存在的模块管理和打包工具并不适合大型的项目,尤其单页面 Web 应用程序.最紧迫的原因是如何在一个大规模的代码库中,维护各种模块资源的分割和存放,维护它们之间的依赖关系,并且无缝的将它们整合 ...