Java初始化顺序
来源:互联网 发布:西门子编程电缆用不了 编辑:程序博客网 时间:2024/06/07 07:19
实例变量的实例化
三个地方:
- 定义实例变量指定初始值
- 非静态初始化块中对实例变量指定初始值
- 构造器中对实例变量指定初始值
其中,1、2中方式比第三种方式更早执行,1、2种执行顺序与它们在源程序中的排列顺序相同。
类变量的初始化
两个地方:
- 定义是指定
- 静态初始化块中指定
这两种方式的执行顺序与它们在源程序中的排列顺序相同
public class StaticInitTest { static int count = 2; static { System.out.println("StaticInitTest静态初始化块"); name = "Java编程"; } static String name = "疯狂java讲义"; public static void main(String[] args) { System.out.println("count类变量的值:" + StaticInitTest.count); System.out.println("name类变量的值:" + StaticInitTest.name); }}
输出:
StaticInitTest静态初始化块
count类变量的值:2
name类变量的值:疯狂java讲义
解析:name刚开始赋值为Java编程
从内存看Java实例化
class Price { final static Price INSTANCE = new Price(2.8); static double initPrice = 20; double currentPrice; public Price(double discount){ currentPrice = initPrice - discount; } }public class PriceTest{ public static void main(String[] args) { System.out.println(Price.INSTANCE.currentPrice); Price p = new Price(2.8); System.out.println(p.currentPrice); }}
输出:-2.8
17.2
解析:
初始化分为以下两个阶段:
1. 系统为Price的两个类变量分配内存空间
2. 按初始化代码的排列顺序执行初始化
Java初始化的内存分配
(注意java在继承变量和方法的时候是有区别的)
当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定。但通过该变量调用它引用的对象的实例方法时,该方法的行为将由它实际所引用的对象来决定。
原因:Java编译器会将父类的方法加到子类中去,而父类中的实例变量则不会。
结论:当一个程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为其父类中定义的所有实例变量分配内存。
public class Test { public static void main(String[] args) { new Derived(); }}class Base{ private int i = 2; public Base(){ //要弄清楚这里的this指向的是子类 //可以通过this.getClass开看 //所以this.display()调用的是子类的,输出的i当然就是子类的i了 this.display(); } public void display(){ System.out.println(i); }}class Derived extends Base{ private int i = 22; public Derived(){ i = 222; } public void display(){ System.out.println(i); }}输出:0
例子2:class Animal{ private String desc; public Animal(){ this.desc = getDesc(); } public String getDesc(){ System.out.println("Animal"); return "Animal"; }}public class Wolf extends Animal{ private String name; private double weight; public Wolf(String name, double weight){ this.name = name; this.weight = weight; } @Override public String getDesc(){ System.out.println("Wolf[name=" + name + " ,weight=" + weight +"]"); return "Wolf[name=" + name + " ,weight=" + weight +"]"; } public static void main(String[] args) { System.out.println(new Wolf("灰太狼", 32.3)); }}
输出:Wolf[name=null ,weight=0.0]
javaSyntax.Wolf@770848b9
解析:因为子类重写了父类的方法,所以实例化子类实例时,不会把父类的那个方法复制过来,所以getDesc()调用的是子类的重写方法
例子3:
class Fruit{ String color = "未确定颜色"; public Fruit getThis(){ return this; } public void info(){ System.out.println("Fruit 方法"); }}public class Apple extends Fruit{ @Override public void info(){ System.out.println("Apple 方法"); } //通过super调用父类的info()方法 public void AccessSuperInfo(){ super.info(); } //尝试返回super关键子代表的内容 public Fruit getSuper(){ return super.getThis(); } String color = "红色 "; public static void main(String[] args) { Apple a = new Apple(); Fruit f = a.getSuper(); System.out.println("a和f所引用的对象是否相同:" + (a == f)); System.out.println("访问a所引用对象的color实例变量: " + a.color); System.out.println("访问f所引用对象的color实例变量:" + f.color); a.info(); f.info(); //调用AccessSuperInfo来调用父类的info()方法 a.AccessSuperInfo(); }}
0 0
- java-java初始化顺序
- Java初始化顺序
- JAVA 初始化顺序
- JAVA初始化顺序
- Java程序初始化顺序
- Java初始化顺序
- [java]初始化顺序
- java变量初始化顺序
- java 初始化顺序
- Java初始化的顺序
- JAVA对象初始化顺序
- java对象初始化顺序
- JAVA 类初始化顺序
- JAVA初始化顺序
- Java 静态初始化顺序
- Java类初始化顺序
- java初始化顺序
- JAVA初始化顺序
- 随机数
- 从1.5k到18k, 一个程序员的5年成长之路
- 图形界面编程_1
- 链接器link.exe 编译器cl.exe 资源编译器rc.exe
- 论缓存之道(1)
- Java初始化顺序
- JBPM-动态的赋值任务申请人
- 北大OJ百练——2721:忽略大小写比较字符串大小
- Good tool for ubuntu, as a linux programer
- A*算法入门
- Intel x86服务器架构中的memory访问之旅
- 黑马程序员_变量的交换练习 三种
- 论缓存之道(2)
- 关于分布式数据库的分库分表