下面的心得只是根据这本书的案例和根据我自己角度和理解,如果你没看过可以和我一起学习,如果您看过这本书,发现我说的有不对地方请指出,共同学习!
第一课 :暂时先略过。以后补
第二课:对象与内存的控制
- 类变量和实例变量:如果初始化两个变量,这两个变量同为类变量或同为实例变量,那么在实例化时要注意实例化的顺序,
// 下面实例变量初始化,将提示非法向前引用
int first = second-1;
int second = 2;
// 下面类变量量初始化,将提示非法向前引用
static int third = four-1;
static int four = 4;
//下面正常状态
int six = seven-1;
static int seven = 7;
上面得粗体字是正常的状态,因为静态变量(类变量)的初始化总在实例变量初始化前。不懂的可以先记住,后面有详解。
类变量和实例变量的属性,通过名字可以就可以知道,实例变量只能通过类的实例对象去访问;类变量就是属于类,直接可以通过类去访问,虽然类变量也可以通过类实例化的对象去访问,但底层最后还是通过类去访问的。所以我个人认为如果直接用类去访问类变量要比通过实例化的类对象去访问类变量的效率要高一些。
实例变量的初始化时机:对于实例变量而言,它属于Java对象本身,每次创建java对象时都需要为实力变量分配存储空间,并执行初始化操作。从语法角度我们可以从三个角度初始化实例变量,如下:
定义实例变量时指定初始值
非静态初始化块中对实例变量指定初始化值
在构造器中对实例变量指定初始化值
其中第1种和第2种方式要早于第3种(在构造器中初始化),第1和2种初始化的方式地位是平等的,所以执行初始化顺序按照在源程序中排列的顺序相同。看下面的代码,试想一下你的结果?
class Cat{
String name;
public Cat(String string) {
System.out.println("执行构造器初始化");
this.name = string;
}
{
System.out.println("执行非静态代码块");
weight = 2.0;
}
//定义时指定初始值
double weight = 4.0;
public String toString() {
return "age="+name+",weight="+weight;
}
}
public class Test {
public static void main(String[] args) {
Cat cat = new Cat("jiafei");
System.out.println(cat);
}
}
//执行结果如下:
// 执行非静态代码块
// 执行构造器初始化
// age=jiafei,weight=4.0
和你想的结果一样么?结果一样证明你比我强啊,我在这里有个疑惑:就是weight的初始化的代码块和直接初始化,定义在代码块后但没报错?其实看过这我才懂真正的原因。其实这两种方式前面说过是平等的地位,经过编译后他们都在构造器初始化的,对于类中的double weight = 4.0;实际分成2次执行步骤:
double weight;//创建java对象时系统为实例变量分配内存空间。
weight = 4.0//这条语句将会被提到java的构造器中执行
下面看看这个简单的例子,并用javap -c JavaToolTest命令查看编译的原理如下:
public class JavapToolTest {
int count = 11;
{
count = 22;
}
public JavapToolTest() {
System.out.println(count);
}
public JavapToolTest(String name) {
System.out.println(name);
}
}
对编译后的JavaToolTest.class运行
javap -c JavaToolTest则看到
D:\software>javap -c -classpath D:\software JavapToolTest
Compiled from "JavapToolTest.java"
public class JavapToolTest extends java.lang.Object{
int count;
public JavapToolTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 11
7: putfield #2; //Field count:I
10: aload_0
11: bipush 22
13: putfield #2; //Field count:I
16: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_0
20: getfield #2; //Field count:I
23: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
26: return
public JavapToolTest(java.lang.String);
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 11
7: putfield #2; //Field count:I
10: aload_0
11: bipush 22
13: putfield #2; //Field count:I
16: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
23: return
}
上面的javap中的粗体表示实例变量都在每个构造器中初始化,而且总位于构造器中所有语句之前。
分享到:
相关推荐
疯狂Java 突破程序员基本功16课1 完全清晰版 5分超低分 挥泪相送啦!这是第二部分 记得下第一部分哇!
《疯狂Java:突破程序员基本功的16课2》是一本深入浅出的编程学习书籍,专注于提升程序员的基础技能。作者李刚以其丰富的教学经验,精心设计了16个课程,旨在帮助读者全面掌握Java编程的核心知识,为日后的职业发展...
疯狂Java 突破程序员基本功16课1 完全清晰版 5分超低分 挥泪相送啦!这是1 记得下第二部分哇!
《疯狂Java:突破程序员基本功的16课》是一本专为Java初学者和有经验的程序员设计的书籍,旨在通过一系列深入浅出的课程,帮助读者巩固和提升编程技能,从而达到“疯狂”提升Java编程能力的目标。这本书涵盖了程序员...
内容讲解的很详细,对java程序员有一个质的提升,欢迎大家下载
对于提升java程序员的基本功十分有帮助,让你深入理解java的内在。也可用于面试
疯狂Java:突破程序员基本功的16课.修订版 疯狂Java:突破程序员基本功的16课.修订版.pdf
在《疯狂JAVA:突破程序员基本功的16课》中,作者深入浅出地探讨了Java编程中的核心概念和技术,旨在提升程序员的基本技能和解决问题的能力。以下是对这些知识点的详细阐述: 1. **Java基础**:Java是一种面向对象...
李刚 著 ISBN:9787115263049
《疯狂Java:突破程序员基本功16课》是一本针对Java程序员进阶的教程,旨在提升读者在编程领域的技能和专业素养。这本书结合了理论与实践,通过16个关键课程,深入讲解了Java编程的核心概念和技术。源代码的提供使得...
Java程序员突破基本功的16课,打好基础,把基本练扎实。
本书把容易被Java程序员所忽视的内容整理成书,介绍了Java的对象、数组的内存分配,介绍了常见集合的实现细节、内存回收的细节、表达式、流程控制、面向对象、异常的“陷阱”,常用的数据结构和算法的实现以及其他...
中高级java开发教程,适合有一定基础的开发人员,不建议新手使用,讲解的比较好,精华部分
在《疯狂Java:突破程序员基本功的16课》中,李刚老师一改枯燥的教学方式,专门面向Java初学者可能会遇到的各种学习问题,由点及面,详细讨论了Java内存管理、Java编程过程中常遇陷阱、常用数据结构的Java实现和Java...
《疯狂JAVA 突破程序员基本功的16课》是一部专为初学者和进阶者设计的编程教程,旨在通过一系列深入浅出的课程,帮助读者巩固和提升JAVA编程的基础技能。这本书的配套源代码提供了丰富的实例,让读者能够在实践中...
疯狂Java_突破程序员基本功的16课(修订版)