《java编程思想》读书笔记(二)第五章(2)
成员初始化
Java尽力保证:所有变量在使用前都能得到恰当的初始化。
对于方法的局部变量,Java会以编译时报错的形式贯彻这种保证,比如:
void f()
{
int i; //这里编译时就会报错,未初始化
}
但是如果是类的数据成员,情况会有所不同。类的每个基本类型数据成员会保证一个默认初始值,通常为0,布尔型就是false,引用类型会为null。
指定初始化
(1 直接在类里定义时写变量等于多少(这样在C++中是不允许的)如,
public class initialV
{
int a=1;
char c = 'c';
//...等等
}
构造器初始化
可以用构造器进行初始化。但应注意:无法阻止自动初始化的进行,它将在构造器之前发生。
public class Counter
{
int i;
Counter()
{
i=7;
}
}
这里,i首先会被置0,然后变成7.对于所以基本类型和对象引用,包括在定义时已经指定初值的变量。这种情况都是成立的。
初始化顺序
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。如下例子
class Window {
Window(int marker) { print("Window(" + marker + ")"); }
}
class House {
Window w1 = new Window(1); // Before constructor
House() {
// Show that we're in the constructor:
print("House()");
w3 = new Window(33); // Reinitialize w3
}
Window w2 = new Window(2); // After constructor
void f() { print("f()"); }
Window w3 = new Window(3); // At end
}
public class OrderOfInitialization {
public static void main(String[] args) {
House h = new House();
h.f(); // Shows that construction is done
}
} /* 输出:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
*///:~
静态数据的初始化
类的静态成员 属于 类 而不是类 的实例。所以 ,无论你创建多少个对象,静态成员指占用一份存储区域。static关键字不能应用于局部变量,因此只能作用于域。初始化方式和非静态一样。
给看一个挺长的例子,看不懂直接调后面的解析。
import static net.mindview.util.Print.*;
class Bowl {
Bowl(int marker) {
print("Bowl(" + marker + ")");
}
void f1(int marker) {
print("f1(" + marker + ")");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table() {
print("Table()");
bowl2.f1(1);
}
void f2(int marker) {
print("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard() {
print("Cupboard()");
bowl4.f1(2);
}
void f3(int marker) {
print("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
print("Creating new Cupboard() in main");
new Cupboard();
print("Creating new Cupboard() in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
} /* 输出:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
*///:~
解析下这个Demo:要执行main()(静态方法) ,必须加载StaticInitialization 类,然后其静态域table和cupboard被初始化,这将导致他们对应的类页被加载,并且由于他们也都包含静态的Bowl对象,因此Bow随后也被加载了。(恍然大悟)
理论得出:静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.b1或Table.b2,name静态的Bowl b1和b2永远都不会被创建。只有在第一个Table对象被创建(或其第一次被访问了静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化
显式的静态初始化
Java允许将多个静态初始化动作组织成一个特殊的“静态字句”(也称 “静态块”),如下。
public class Spoon {
static int i;
static {
i = 47;
}
} ///:~
尽管上面的代码看起来像个方法,但它实际只是一段跟在static关键字后面的代码。与其他静态初始化动作一样,这段代码只执行一次:同样的时间,当第一次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类)。
非静态实例初始化
用来初始化每一个对象的非静态变量。如下
class Mug {
Mug(int marker) {
print("Mug(" + marker + ")");
}
void f(int marker) {
print("f(" + marker + ")");
}
}
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
print("mug1 & mug2 initialized");
}
Mugs() {
print("Mugs()");
}
Mugs(int i) {
print("Mugs(int)");
}
public static void main(String[] args) {
print("Inside main()");
new Mugs();
print("new Mugs() completed");
new Mugs(1);
print("new Mugs(1) completed");
}
} /* 输出:
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
*///:~
这是无论调用了哪个显式构造器,某些操作都会发生。从输出中 可以看到实例化字句 是在构造器之前执行的。
《java编程思想》读书笔记(二)第五章(2)的更多相关文章
- 《Java编程思想》笔记 第十五章 泛型
1 泛型 “泛型”意思就是适用于许多类型. 使用泛型的目的之一: 指定容器持有什么类型,让编译器确保正确性,而不是在运行期发现错误. 这个容器可以看成是有其他类型对象作为成员的类,而不单单只是JDK中 ...
- Java编程思想读书笔记_第7章
final关键字类似const: import java.util.*; public class FinalData { static Random rand = new Random(47); f ...
- Java编程思想读书笔记_第6章
如何创建一个包: 比如创建一个包名为com.huawei 则在一个目录下如(d:\java)创建目录com/huawei 然后在huawei目录下创建一个文件Assist.java package c ...
- Java编程思想读书笔记_第三章
本章提到的关于==的部分,一个完整的实验如下: class Test { public static void main(String[] args) { Integer i = new Intege ...
- Java编程思想读书笔记_第8章
覆盖私有方法 class Father { private void f() { System.out.println("Father::f()"); } public stati ...
- Java编程思想读书笔记_第6章(访问权限)
四种访问权限: public private 包访问权限 protected 如果没有明确指定package,则属于默认包 package access.dessert; public class C ...
- JAVA编程思想读书笔记(五)--多线程
接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...
- JAVA编程思想读书笔记(二)--容器
接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...
- JAVA编程思想读书笔记(三)--RTTI
接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...
- JAVA编程思想读书笔记(四)--对象的克隆
接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...
随机推荐
- Unbalanced calls to begin/end appearance transitions for **
在自定义UITabBarController中点击视图跳转的时候,有可能就出现这个问题, 解决方法就是在自定义的UITabBarController中的视图显示消失通知方法中添加如下方法: - (vo ...
- c语言实现牛顿迭代法
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<float.h> #inc ...
- java中的foreach循环
foreach语句是java5的新特征之一,在遍历数组.集合方面,foreach为开发人员提供了极大的方便. foreach语句是for语句的特殊简化版本,但是foreach语句并不能完全取代for语 ...
- Ubuntu下iperf的安装
(1)下载 链接:http://sourceforge.net/projects/iperf/files/?source=navbar 资源:iperf-2.0.5.tar.gz (2)解压 #t ...
- HTMlhleper
@{ ViewBag.Title = "Index";} <h2>Index</h2> <div> @{ int id=12121; var I ...
- .NET笔试题集(二)
1.using关键字有什么用?什么是IDisposable? using可以声明namespace的引入,还可以实现非托管资源的释放,实现了IDisposiable的类在using中创建,using结 ...
- iOS 自动化打包
理想的情况:不打开工程的情况下,直接双击就能打包出一个IPA文件,这样就可以让测试直接使用 itools 进行安装. 分如下两种情况: 1)不依赖cocoapod 管理项目的自动化. 如果没有一个简 ...
- Jenkins_Maven_Git 持续集成及自动化部署 GentOS版
1.安装JDK JDK下载: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 新 ...
- Javascript轮播 支持平滑和渐隐两种效果(可以只有两张图)
先上两种轮播效果:渐隐和移动 效果一:渐隐 1 2 3 4 效果二:移动 1 2 3 4 接下来,我们来大致说下整个轮播的思路: 一.先来看简单的,移动的,先上来一个图----移动效果图: 说明: ...
- [解决方案] pythonchallenge level 6
查看页面代码,知道找zip www.pythonchallenge.com/pc/def/channel.zip,查看zip下的readme.txt知道从90052,跑一遍知道要收集zip的comme ...