05 初始化与清理

来源:互联网 发布:网店美工是什么专业 编辑:程序博客网 时间:2024/06/08 13:47

1、用构造方法确保初始化

       1)如果类中没有构造方法,编译器自动创建一个无参的构造方法;
       2)如果类中已有构造方法,编译器不会i创建一个无参的构造方法;

2、方法重载

规则:1)发生在同一类中;
            2)方法名相同,参数列表不同(参数类型、参数顺序、参数个数);
            3)返回值不同不构成方法重载;

注意点:
           参数类型提升的问题!
            
void f1(byte x){      System.out.println("f1(byte)");}void f1(char x){      System.out.println("f1(char)");}void f1(short x){      System.out.println("f1(short)");}void f1(int x){      System.out.println("f1(int)");}void f1(long x){      System.out.println("f1(long)");}void f1(float x){      System.out.println("f1(float)");}void f1(double x){      System.out.println("f1(double)");}
若是传入5,则调用void f1(int x);没有int则找long,float,double
若是传入byte 5,则调用void f1(byte x);若没有void f1(byte x),则找short ,int ,long,float,double
若是传入short 5,则调用void f1(short x);若没有void f1(short x),则找int, long,float,double
若是传入char 5,则调用void f1(char x);若没有void f1(char x),则找int, long,float,double
说明:如果传入的参数类型小于声明的形式,就会按照byte,short ,int ,long,float,double的顺序找方法,
            如果传入的是char类型,按照int ,long,float,double的顺序找方法;
            如果传入的参数类型大于声明的形式,会报错,若要调用需要强制转换。

(编程注意点)

3、this关键字

1)含义:指代当前对象。

2)在构造方法中调用构造方法。如this(),this(1),
       注意点:构造方法必须置于最起始处; 
                       在构造方法中,this只能调用一个构造方法,不能有2个以上;
public class A{     public A(){}     public A(int x){//code. . .}     public A(int x ,int y){           this();   //起始位置           //this(1);  error,不能调用2次           //code. . .     }}
        结合super的一点:若是使用this调用构造方法,就不能使用super调用父类的构造方法。
        简单的理解是:this、super调用自己和父类的构造方法都需要放在第一行(起始位置),只能存其一;
        深入的理解是:用this调用构造方法时,会先调用父类的构造方法就是super。
                    
3)注意:static中不能使用this。因为this是当前对象,而static是属于整个类的。

(笔试常考)

4、清理与垃圾回收

(1)垃圾收集器工作方式

java的垃圾回收器能够以单独的线程在后台运行,并依次检查每个对象。通过更改对象表项,垃圾回收器可以标记对象、移除对象、移动对象和检查对象。
垃圾回收器是自动运行的,一般情况下,无须显示地请求垃圾回收器。
程序运行时,垃圾回收器会不时检查对象的各个引用,并回收对象所占用的内存。
总结:GC即垃圾回收机制,指JVM用于释放那些不再使用的对象所占用的空间。

(2)两个与垃圾回收有关的函数
System.gc()
java提供的一种强制执行垃圾回收的方法。调用该方法并不表示一定能够启动垃圾回收,它只是想JVM发出要垃圾回收申请。不一定会回收资源

Object类的finalize();  
GC的工作原理的“假定”:一旦垃圾回收器准备好释放对象占用的存储空间,会首先调用该对象的finalize()方法,并且在下一次垃圾回收动作发生时,才会真正的回收对象占用的空间。
java提供了默认机制终止该对象来释放资源,finalize()。当该方法返回后,对象消失,垃圾回收器开始执行。一定会回收垃圾
finalize()的用途:java的垃圾回收器只负责回收无用的对象(用new创建的,分配在堆上),finalize()可以应对这种情况。

(3)垃圾回收器如何工作?
综述:垃圾回收器对对象重新排练,实现一种高速的、有无限空间可供分配的堆模型。
主要有如下方法实现:
  • 引用计数
方式:每个对象都含有一个引用计数器,当有引用连接时,引用计数加1;当引用离开作用域或被置为null,引用计数减1。垃圾回收器会在含有全部对象列表上遍历,若某个对象的引用计数为0,就释放其占用的空间。
缺陷这个过程会在程序生命周期中持续发生(程序未停止),同时对于对象之间存在循环引用,可能会出现“对象应该被回收,但是计数不为0”的情况,对于垃圾回收器来说,定位交互自引用的对象组工作量极大。
应用:未被应用到任何一款java虚拟机中。
  • 停止-复制
方式:解决“交互自引用的对象组”问题,引出找活着的对象的方法,采用停止-复制的方法。
停止-复制:先暂停程序的运行(所以它不属于后台回收模式),然后把将所有存活的对象从一个堆复制到另一个堆,留下的没有复制的都是垃圾。当对象被复制到新堆,它们是一个个挨着的空间,紧密排列
缺陷:效率低。从一个堆复制到另一个堆,需要维护2个堆;在少量的垃圾情况下,仍2个堆的空间。
应用:未被sun公司采纳。
  • 标记-清扫
有些jvm为了解决上述缺陷:在少量的垃圾情况下,仍2个堆的空间,引入了标记-清扫方法与自适应方法一起。
标记-清扫:需要暂停程序,遍历所有的引用,找出存活的对象进行标记,没有标记的对象就被清理。这时内存空间不连续,重整内存空间
应用:sun早期版本采用。

  • 自适应的、分代的、停止-复制、标记-清扫”式垃圾回收器
自适应:可以根据情况,切换回收方式。
分代的:采用一种“块”的方式。
:java虚拟机,内存分配以较大的“块”为单位,对象较大,占用单独的块。每个块有相应的代数记录它是否存活。
整个的工作方式:①垃圾回收器在回收垃圾时,将存活的对象可以往废弃的块中拷贝对象,节省开销;大的未废弃的块不会复制,只是代数增加,内含小对象的的块被完整复制,然后对重整分配的块;②垃圾回收器定时进行完整的清理动作;③java虚拟机进行监视,若对象很稳定,垃圾回收效率低,就切换到“标记-清扫”的方式;继续监视“标记-清扫”方式,若堆空间出现很多碎片,就切换回“停止-复制”方式。
应用:基本上sun采用的就是这种方式。

(面试经常问)

5、初始化

5.1类成员变量初始化

  • 普通成员变量初始化:
1)类的普通成员变量若为基本类型,有默认值;
2)可以在定义类的时候,指定成员变量的初始化;如private int  age = 15;;
3)构造器进行初始化;
4)代码块进行初始化,如:      
private int i;  {      i = 1;}
  • static成员变量的初始化:
1)类的静态成员变量若为基本类型,有默认值;为引用类型,其值为null,
2)可以在定义类的时候,指定成员变量的初始化;如public static  int  age = 15;;
3)使用静态代码块初始      
public static int i;  static  {      i = 1;}

  • 初始化顺序(笔试常考)

①静态成员变量或静态代码库(顺序决定先后)

②普通成员变量或代码块(顺序决定先后)

③构造方法

说明:再讲继承的时候,结合父类,继续补充初始化顺序。

5.2数组初始化

1)int []  a1={1,2,3,4}

2)一个数组的引用给另一个数组:int[] a2 = a1;它们公用一个数组内存
public static void main(String[] args) {    int[] a1 = {1,2,3,4,5};    int[] a2;    a2 = a1;    for(int i = 0; i < a2.length; i++ ){        a2[i] = a2[i]+1;    }    for(int i = 0; i < a1.length; i++ ){         System.out.println(a1[i]);    }} //ouput:2 3 4 5 6



3)int [] a1 = new int[5];  加遍历数组初始化。
      说明:若是我们不进行初始,基本类型则使用使用默认初始化,如上面a1 是0,0,0,0,0
                  引用类型都是null;
                  必须进行遍历初始化外,还可以使用如下方式:                    
int a1 = new int[]{1,2,3,4,5}Integer a2 = new Integer[] {new Integer(1),new Integer(2),3,4,5}
tips:
与打印数组有关的函数:Arrays.toString(type array);  用于打印一维数组

6、可变参数列表

public static void main(String[] args) {     method1(1,'a','b','c');}public static void method1(float i, char... args{    System.out.println(Arrays.toString(args));}


说明:可变参数部分,必须是写在最后面,否则报错;可变参数的原理是数组,args是数组。

7、枚举

   
public enum Spiciness {NOT,MILD,MEDIUM,HOT,FLAMING}public class Test{    public static void main(String[] args) {          for(Spiciness s: Spiciness.values()){                System.out.println(s+",ordinal:"+s.ordinal());          }    }}NOT,ordinal:0MILD,ordinal:1MEDIUM,ordinal:2HOT,ordinal:3FLAMING,ordinal:4

   
记住2个函数:枚举类名.values()获取所用的枚举值
                          枚举值.ordinal()返回枚举值是排第几声明的,从0开始





0 0