Java4Android类和对象的初始化详解

1,成员初始化

Java尽力保证:所有变量在使用前都能够恰当的初始化。

1)方法的局部变量。Java以编译时错误来贯彻这种保证。eg:

void f(){
    int i;
    i++; //Error , i not initialized
}

2)类的数据成员。如果是基本类型,他们都会有一个初始值;如果是对象引用,那么这个引用将会被初始化为null。

指定初始化

如果想为某个变量赋值,该怎么做?

1)直接在定义类成员变量的地方为其赋值(注意,C++里面是不可以的,尽管C++新手们总想这么做)

class Depth{}

public class InitialValues{
    boolean bool = true;
    char ch = 'x';
    int i = 999;
    Depth d = new Depth();
}

2)调用某个方法来提供初始值。

public class MethodInit{
int i = f();
int f(){return 11;}
}

这个函数还可以带参数,但必须是初始化过的参数。

public class MethodInit2{
int i = f();
int j = g(i);
int f(){
    return 11;
}
int g(int n){
   return n*10;
}
}

但下面的写法确实错误的

public class MethodInit3{
// int j = g(i) ; //Illegal forward reference
int i = f();
int f(){return 11;}
int g(int n){return n*10;}
}

显然,上述程序的正确性取决于初始化的顺序。编译器会发出“向前引用”的警告。

上述这种在定义的地方就初始化,简单快捷,这样创造出来的每个对象都会具有相同的值。

2,构造器初始化

在C++里面叫做构造函数,这里我们叫做构造器,都一个东西。上一节讲到的自动初始化是一定会被执行的,而且会在构造器之前执行。

public class Counter{
int i;
Counter(){i = 8;}
}

上述代码,i首先会被置为0,然后变为7.

初始化顺序

在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,他们仍然会在任何方法(包括构造器)被调用之前得到初始化。

class Window{
Window(int marker){print("window("+marker+")");}
}
class House{
window w1 = new Window(1);
House(){
print("house()");
w3 = new Window(33);
}
Window w2 = new Window(2);
void f(){print("f()");}
Window w3 = new Window(3);

}
public class OrderOfInitialization{
public static void main(String[] args){
    House h = new House();
   h.f();
}
}

/**Output**/
/*
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()*/

静态数据的初始化

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();
}
/**output*/
/*
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)
*/

请务必细心的看上述代码和结果。最好自己能够运行一遍。

初始化的顺序是先静态对象,后非静态对象。

静态初始化只有在必要的时刻才会进行。如果不创建Table对象,也不引用Table.b1,Table.b2,那么静态的Bowl b1 和b2 永远都不会被创建。下面的步骤我们会解析为什么。

对象创建过程

总结下对象创建的过程。假如有一个名为Dog的类:

1)即使没有显式的使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成是静态方法),或者Dog类的静态方法,静态域首次被访问的时候,Java解释器必须查找路径,以定位Dog.class文件。

2)然后载入Dog.class(这将创建一个Class对象),有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。

3)当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。

4)这块存储空间会被清零。这就自动的将Dog对象中的所有基本类型数据都设置成了默认值,而引用则被设置成了null。(再次强调方法内部的局部变量不会被初始化,如果使用未初始化的局部变量会提示编译错误)。

5)执行所有出现于字段定义处的初始化动作。

6)执行构造器。

显式的静态初始化(静态块)

Java允许将多个静态初始化动作组织成一个特殊的“静态子句”(也叫静态块)。

public class Spoon{
static int i;
static {
    i = 47;
}
}

上述代码和静态初始化动作是一样的,代码仅在必要的时刻仅执行一次。

class Cup{
Cup(int marker){
    print("Cup("+marker+")");
}
void f(int marker){
    print("f("+marker+")");
}
}

class Cups{
static Cup cup1;
static Cup cup2;
static {
    cup1 = new Cup(1);
    cup2 = new Cup(2);
}
Cups(){
    print("Cups()");
}
}

public class ExplicitStatic{
    public static void main(String[] args){
     print("Inside main()");
     Cups.cup1.f(99);//(1)
}
    //static Cups cups1 = new Cups();//(2)
    //static Cups cups2 = new Cups();//(3)
}
/**output*/
/*
Inside main()
Cup(1)
Cup(2)
f(99)
*/

上述代码无论是运行(1)还是把(1)注释了运行(2),Cups的静态初始化都会得到执行。(3)也可以打开看看,无关紧要,因为静态初始化动作只进行一次。

非静态实例初始化

它在静态初始化之后,在构造函数之前,前面我们讲述过这个步骤。我们来看一段代码:

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);
    printf("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");
}
}
/** output*/
/*
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
*/

这种语法对于支持“匿名内部类”的初始化是必须的。

累了。今天学习到这里。

时间: 2024-08-29 16:42:12

Java4Android类和对象的初始化详解的相关文章

PHP类和对象函数实例详解

1. interface_exists.class_exists.method_exists和property_exists: 顾名思义,从以上几个函数的命名便可以猜出几分他们的功能.我想这也是我随着对PHP的深入学习而越来越喜欢这门编程语言的原因了吧.下面先给出他们的原型声明和简短说明,更多的还是直接看例子代码吧. bool interface_exists (string $interface_name [, bool $autoload = true ]) 判断接口是否存在,第二个参数表示

JAVA 类和对象基础知识详解

/*文章中用到的代码只是一部分,需要源码的可通过邮箱联系我 [email protected]*/ 和C++一样,JAVA也是一门面向对象的语言,其基础和核心是类和对象.而面向对象的思想是来源与显示生活,自然在学习时联系现实生活会理解得更深. 1.对象 首先,什么是对象? 在现实生活中只要是一个具体的物体或者一个具体的事物就是一个对象.你所看到的任何一个物体,你所想的任何一个物体都是对象,比如:某一台电脑,某一个人 其次,知道了什么是对象之后便是去描述.你会从哪些方面去描述对象?分别有些什么内容

Qt on Android: Qt Quick 组件与对象动态创建详解

在<Qt on Android: Qt Quick 事件处理之信号与槽>一文中介绍自定义信号时,举了一个简单的例子,定义了一个颜色选择组件,当用户在组建内点击鼠标时,该组件会发出一个携带颜色值的信号,当时我使用 Connections 对象连接到组件的 colorPicked 信号,改变文本的颜色. 当时用到的 Component . Loader 两个特性,一直没来得及介绍,可能很多人都还在雾里看花呢.这次呢,我们就来仔仔细细地把他们讲清楚. 请给我的参赛文章<Qt on Androi

struts2.0中Action的对象生命周期详解!!(转)

原文出处:http://blog.csdn.net/wxy_g/article/details/2071662 有很多人问Struts2.0中的对象既然都是线程安全的,都不是单例模式,那么它究竟何时创建,何时销毁呢? 这个和struts2.0中的配置有关,我们来看struts.properties ### if specified, the default object factory can be overridden here ### Note: short-hand notation is

CSS中伪类及伪元素用法详解

原文:CSS中伪类及伪元素用法详解 伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的读者可以自己尝试: :active  大致效果为用鼠标点击时,元素增加特效,鼠标松开时,特效消失.多用在按钮的点击上. 写法: 这里id为box的是一div块,在css中首先设置了他的基本样式,下面为加入:active伪类后需要修改的样式. 未点击时: 点击之后: :active.:hover.:

【转载】图说C++对象模型:对象内存布局详解

原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有所不同.文章如果有解释不清.解释不通或疏漏的地方,恳请指出. 回到顶部 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各种支持的底层

Java基础——类和对象的初始化过程

本节把类和对象的初始化所涉及到的所有代码块阐述一边. 示例代码: 1 public class Demo { 2 private static String name; 3 private String age; 4 5 // 主函数 6 public static void main(String[] args) { 7 Demo demo = new Demo(); 8 9 } 10 11 // 构造函数 12 public Demo() { 13 System.out.println("我

java定时任务类Timer和TimerTask用法详解

原文:java定时任务类Timer和TimerTask用法详解 代码下载地址:http://www.zuidaima.com/share/1550463277550592.htm package com.zuidaima.util; import java.io.IOException; import java.util.Timer; import test.MyTask; /* * 本类给出了使用Timer和TimerTaske的主要方法,其中包括定制任务,添加任务 * 退出任务,退出定时器.

Java对象初始化详解

出处:http://blog.jobbole.com/23939/ 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Java如何执行对象的初始化做一个详细深 入地介绍(与对象初始化相同,类在被加载之后也是需要初始化的,本文在最后也会对类的初始化进行介绍,相对于对象初始化来说,类的初始化要相对简单一 些). 1.Java对象何时被初始化 Java对象在其被创建时初始化,在Java代码中,有两种行为可以引起对象的创建.其中比较直观的一种,也就是通常所