CoreJava Day 5

对象引用: reference

Object o = new Object();

其中o就是引用变量,就好比一个人的名字,别人喊你名字的时候,你就会有反应一样,比如你的上司,通过你的名字,可以对你进行发号施令。

通过操作引用变量,可以对一个对象发布命令。

 

引用变量和对象不是同一个概念。

 

 

基本类型转换:

比如说一个方法或者变量接受一个较小的类型作为参数,而实际传入一个较大的,在传入的时候,就必须做  “类型转换”

如:

double d =3.1415d;

int i  = (int)3.1415d;

 

tij中称之为“窄化转换” narrowing conversion

以后还有遇到“类类型转换”也可以说 “造型”(Casting)

 

 

构造器:Constructor

 

确保了正确的初始化清理

 

如果没有构造器,java中将不允许创建对象,所以你可以完全的掌控,非常安全

 

如果通过构造器产生了对象,那对象会再某一时刻被Garbage所回收。但是垃圾回收不需要进行手工干预,即使手工干预了,也不一定会立刻执行,可以通过调用System.gc()来召唤垃圾回收器,garbage collector是一个低优先级的线程。

调用finalize()方法,在一个对象被垃圾回收器回收前,首先会调用对象的此方法,所有对象都有此方法,从Object中继承二来。

 

重写Object类中的finalize()方法,来实现一个对象回收前的清理或者检查工作。
      
      

 

TIJ中的一例:(此例在原书3rd(英文版)中第187页,原书3rd (中文版)104

public class Book {

    boolean checkedOut = false;

    Book(boolean checkOut) {

       checkedOut = checkOut;

    }

    void checkIn() {

       checkedOut = false;

    }

    public void finalize() {

       if (checkedOut)

           System.out.println("Error: checked out");

    }

}

class TerminationCondition {

    public static void main(String[] args) {

       Book novel = new Book(true);

       // Proper cleanup:

       novel.checkIn();

       // Drop the reference, forget to clean up:

       new Book(true);

       // Force garbage collection & finalization:

       System.gc();

    }

}

输出结果为:

Error: checked out

没有引用指向new Book(true);所以改对象被回收了,但是回收前调用了对象的finalize()方法,做了检查工作。

 

垃圾回收器的2种工作模式:

VM监视,进行模式切换,是“自适应”的。

1.“停止-复制模式-- 堆复制,将存活的对象从一个堆复制到灵一个堆,而且复制到新堆的时候,对象是紧凑排列的。

2.“标记-清扫”--扫描当前堆中对象,并且释放掉那些垃圾对象,但是,不是连续的

 

关于finalize()当没有引用指向对象时,在垃圾回收器回收该对象之前,必定要调用finalize()方法,此方法在Object中为空实现。

 

 

 

 

成员初始化的顺序

 

永远都无法阻止Field的自动初始化的进行!

Class Num{

    int i;

    int a = 6;

    Num(){

       i=6;

       a=7;

    }

   

   

 

}

 

i一定会先被置0,然后才会变成6

a 也一样,即使初始了值也会先变成0,然后赋值为6,最后通过构造器变为7

 

初始化顺序

 

1.字段自动初始化默认值 :

 基本类型: 0  ,boolean false  char “/u 0000”

 

2.静态代码块产生一个类的对象或访问一个类的静态成员(字段和方法,虽然没有产生这个类的对象),就会触发执行,只执行一次。

static{

int i=3;

}

 

3.非静态代码块 --  产生类的对象的时候,执行,每产生一个对象,都会执行一次,有点像构造器,但是先于构造器之前执行。

{

int i=3

}

3.构造器 --产生类的对象的时候,执行,每产生一个对象,都会执行一次。晚于非静态代码块

 

看一个简单的证明例子:

public class InitializationDemo {

    // auto-Initialization

    int i; // 1st

 

    static String str = "load once";

    //static block                    

    static {

       System.out.println(" ** static block ** ");

    }

    // non-static block Initialization

    {

       i = 6; // 2nd

       System.out.println("non-static block_1 i = " + i);

       i++;

       System.out.println("non-static block_2 i =" + i);

    }

 

    // Constructor Initialization

    public InitializationDemo() {

       i++; // 3rd

    }

}

 

class Test {

    public static void main(String... args) {

       // static-block loading only once

       System.out.println(InitializationDemo.str);

       // create two instance,so non-static block has been loaded twice

       InitializationDemo id1 = new InitializationDemo();

       InitializationDemo id2 = new InitializationDemo();

       // serialza initialization "i"

       System.out.println("main method: id1 field i = " + id1.i);

       System.out.println("main method: id2 field i = " + id2.i);

    }

}

输出结果:

** static block **

load once

non-static block_1 i = 6

non-static block_2 i =7

non-static block_1 i = 6

non-static block_2 i =7

main method: id1 field i = 8

main method: id2 field i = 8

 

从这个结果能证明上述初始化顺序。

 

 

 

数组的初始化:

 

数组是一种 相同类型的,用同一个标识名,封装在一起的对象序列。

 

数组通过标识名和下标操作符[ ]来操纵

 

基本类型数组:

 

数组中只能存放的是基本数据类型和引用,不能存放对象。

 

int[] a1=new int[5];//封装了一个大小为5个单位int类型的,标识名为a1的数组

int[] a2=new int[]{1,2,3,4}; //定义封装的同时,初始化数组的大小

a1[3]=5;//通过下标操作符复制

int i=a1[3];//通过下标操作符取值

 

引用数组:    

Integer[] it = new Integer[]{new Integer(5),new Integer(6)};

int a=it[0];

int b=it[1]; 

 

假设有个Person类,其中有talk()方法,声明引用数组:

Person[] p2 =new Person[]{new Person(),new Person()};  

p2[0].talk();

相当于

 

Person p = new Person();

p.talk();

 

这里的p2[0]相当于p,都只是堆内存中某个对象的引用变量

 

数组不同于集合:

集合中存放的是对象,任何事物在java中都是对象。虽然集合和数组非常相似。

集合类中有很多工具提供,可以自己扩充容量以适用需求。集合的详细内容在以后再作介绍

 

这是一个集合例子的代码片断:

假设有个Person类,其中有talk()方法,声明引用数组:

Person person1 = new Person("javier", 24, "male");

       Person person2 = new Person("Michale", 23, "female");

 

       ArrayList<Person> list = new ArrayList<Person>();

        list.add(person1);

       list.add(person2);

      

       // 方法一,通过集合下标取第一个元素,并调用对象的方法

       list.get(0).talk();

       // 方法二,通过迭代器,只遍历第一个元素,并调用对象的方法

       list.iterator().next().talk();

 

       // 方法三 通过迭代器遍历所有元素,并调用对象的方法

       Iterator<Person> iter = list.iterator();

       while (iter.hasNext()) {

           iter.next().talk();        

       }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值