zoukankan      html  css  js  c++  java
  • Java基础:初始化与清理

    1、构造器

    每个类都必须至少有一个构造器,如果没有显式的定义,编译器会自动为该类创建一个隐式的无参构造器(无参构造器也称为默认构造器)。

    构造器没有返回值,不会返回任何东西(返回值为空没有返回值是两码事),但是下面的语句会让人疑惑:

    1 Object object = new Object();

    实际上是new表达式返回了新建对象的引用,构造器没有返回任何东西。

    2、方法的重载

    方法名、方法参数表(参数数量、参数类型、参数顺序)区分了两个的方法。

    改变参数顺序也可以实现方法重载,但是不推荐使用,因为不利于维护和使用。一般是利用参数数量、类型来实现方法重载。

    由于基本类型能从一个“较”小的类型自动提升到一个“较大”的类型,所以当重载涉及到基本类型时,容易发生混淆。看下面的代码:

     1 import static java.lang.System.*;
     2 
     3 public class Overload {
     4 
     5     /**
     6      * @param args
     7      */
     8     public static void main(String[] args) {
     9         byte b = 1;
    10         char c = 1;
    11         short s = 1;
    12         int i = 1;
    13         long l = 1;
    14         float f = 1;    //f=1 没有问题,因为1是整数,可以被提升为float而不丢失精度
    15         //! float f = 1.0;    //f=1.0则会提示错误,因为小数默认是double。需要进行强制类型转换,或者通过 f=1.0F 明确告诉编译器我要定义一个float型数据
    16         double d = 1;    // d=1,提升为double,正确; d=1.0,正确。
    17 
    18         
    19         Overload ol = new Overload();
    20         ol.f1(1); //整数字面常量被看做是int型,所以调用f1(int i)
    21         ol.f1(1.0); //小数字面常量被看做是double型,所以调用f1(double i)
    22         
    23         //! ol.f2(b);    //错误,byte不会被自动提升到char
    24         //! c=b            //错误,byte不会被自动提升到char
    25         ol.f3(b);         //byte会自动提升到short,所以调用f3(short i)
    26         
    27         //首先寻找完全匹配的方法,有则调用,反之如果实际传入的数据类型小于方法声明的形参类型,实参会被就近提升,然后调用相应的方法。自动转型遵循下面规律:
    28         //byte < short < int < long < float < double
    29         //char < int < long < float < double
    30 
    31     }
    32     
    33     void f1(byte i) {
    34         out.println("f1(byte i)");
    35     }
    36     void f1(char i) {
    37         out.println("f1(char i)");
    38     }
    39     void f1(short i) {
    40         out.println("f1(short i)");
    41     }
    42     void f1(int i) {
    43         out.println("f1(int i)");
    44     }
    45     void f1(long i) {
    46         out.println("f1(long i)");
    47     }
    48     void f1(float i) {
    49         out.println("f1(float i)");
    50     }
    51     void f1(double i) {
    52         out.println("f1(double i)");
    53     }
    54     
    55     void f2(char i) {
    56         out.println("f2(char i)");
    57     }
    58     void f3(short i) {
    59         out.println("f3(short i)");
    60     }
    61 }

    注意,不能用返回值类型来区分方法

    3、this

    表示调用方法的当前对象的引用,只能在方法内部使用。

    this对于将当前对象传递给其他方法也很有用,例如:

     1 class Peeler {
     2     static Apple peel(Apple apple) {
     3         //...
     4         //...
     5         return apple;
     6     }
     7 }
     8 
     9 class Apple {
    10     Apple getPeeled() {
    11         return Peeler.peel(this);    //为了将自身传递给外部方法,Apple必须使用this关键字
    12     }
    13 }

    this的另一种用法是在一个构造器中调用另一个,但是必须位于构造器方法体的第一行。

    static方法中不存在this

    4、类被加载的时机

    当调用类中的静态成员变量、静态方法、创建该类的对象时,即使用该类时,类才被加载。

    5、初始化顺序

    类被加载时,静态成员、静态块中的变量依照定义顺序完成初始化;

    创建对象时,先完成静态成员、静态块中的变量的初始化,然后初始化非静态成员,最后调用构造器。

    静态成员、静态块中的变量尽在类被加载时被初始化一次,之后不再被初始化。

     1 public class Initialization {
     2     public static void main(String[] args) {
     3         Cups cups = new Cups();
     4         Cups cups2 = new Cups();
     5         Cup cup_ = Cups.cup1;
     6         Cup[] cup_arr = {new Cup(12),new Cup(11)};
     7         //! Cup cup8 = Cups.cup7;    //error, can not be seen 
     8     }
     9 }
    10 
    11 class Cup {
    12     public Cup(int i) {
    13         System.out.println("cup is "+i);
    14     }
    15     void f(int i) {
    16         System.out.println("f() is "+i);
    17     }
    18 }
    19 
    20 class Cups {
    21     static Cup cup1, cup2, cup3 = new Cup(3);
    22     Cup cup4 = new Cup(4), cup5;
    23     static {
    24         cup1 = new Cup(1);
    25         cup2 = new Cup(2);
    26         cup3 = new Cup(33);
    27         Cup cup7 = new Cup(7);        //local variable
    28     }
    29     public Cups() {
    30         System.out.println("Cups()");
    31     }
    32     static Cup cup6 = new Cup(6);
    33 }
    34 //output:
    35 /*
    36 cup is 3
    37 cup is 1
    38 cup is 2
    39 cup is 33
    40 cup is 7
    41 cup is 6
    42 cup is 4
    43 Cups()
    44 cup is 4
    45 Cups()
    46 cup is 12
    47 cup is 11
    48 */

    静态块中,

    a、其所操作的field须是静态的

    b、静态的field初始化顺序与其定义顺序一致,包括静态块中的初始化语句

    c、静态块中定义的变量时局部变量,但同样是静态的。如上面的cup7。

    6、数组初始化

    数组属于对象,数组变量是其引用。

    int [] array = new int[8];    //array是一个数组引用,它指向一个int型数组对象

    三种定义数组的方式:

    1 int [] int_arr_1 = {1,2,3};
    2 Object [] obj_arr_2 = {new Object(), new Object()};
    3 //这种方式下,数组的初始化必须位于数组的定义处
    int [] int_arr_2 = new int[3];
    for(int i = 0; i<3; i++) {
        int_arr_2[i] = i;
    }
    //这种定义方式在定义时为数组对象本省分配了空间,数组元素执行默认初始化,即如果是基本类型的数组,初始化为基本类型的默认初始值;如果是引用类型的数组,则初始化为空,此时在使用数组元素之前需要对数组元素进行初始化,使其指向一个实际的对象
    1 int [] int_arr_1 = new int[]{1,2,3};
    2 Object [] obj_arr_2; 
    3 obj_arr_2 = new Object[]{new Object(), new Object()};
    4 //这种初始化的位置很随意,多用与方法调用,如:
    5 
    6 //方法定义
    7 void test(String[] s) {//...}
    8 //方法调用
    9 test(new String[]{"now", "you", "see"});

    下面这种方式是正确的

    1 Integer arr = {new Integer(1), new Integer(2), 3};
    2 //SE 5出现的auto-boxing功能

    7、可变参数

     1 public class Initialization {
     2     static void printArray(Object... args) {
     3         for (Object object : args) {
     4             System.out.println(object + "------" + object.getClass());
     5         }
     6     }
     7     
     8     public static void main(String[] args) {
     9         printArray(1, 2, 3);//自动包装
    10         printArray(new Integer(11),new Integer(12));
    11         printArray(new Integer(11),new Float(3.14));
    12         printArray(47,3.14f,11.11);
    13         printArray(new Integer[] {41,42,43,44});//提示:The argument of type Integer[] should explicitly be cast to Object[] 
    14                                                 //for the invocation of the varargs method printArray(Object...) from 
    15                                                 //type Initialization. It could alternatively be cast to Object for 
    16                                                 //a varargs invocation
    17         printArray((Object[])new Integer[] {413,423,433,443});
    18         printArray();                            //可以为空        
    19     }
    20 }
    21 //output
    22 /*
    23 1------class java.lang.Integer
    24 2------class java.lang.Integer
    25 3------class java.lang.Integer
    26 11------class java.lang.Integer
    27 12------class java.lang.Integer
    28 11------class java.lang.Integer
    29 3.14------class java.lang.Float
    30 47------class java.lang.Integer
    31 3.14------class java.lang.Float
    32 11.11------class java.lang.Double
    33 41------class java.lang.Integer
    34 42------class java.lang.Integer
    35 43------class java.lang.Integer
    36 44------class java.lang.Integer
    37 413------class java.lang.Integer
    38 423------class java.lang.Integer
    39 433------class java.lang.Integer
    40 443------class java.lang.Integer
    41 */

    涉及重载时,考虑基本数据类型的提升问题

     1 static void F(Character... args) {
     2     System.out.println("Character... args");
     3 }
     4 
     5 static void F(float f, Character... args) {
     6     System.out.println("Character... args");
     7 }
     8 
     9 public static void main(String[] args) {
    10     F(1,'2');
    11     //!F('2','2');//'2'能够被提升为float,造成歧义,编译器不知道应该调用哪个函数
    12 }
     1 static void F(Character c, Character... args) {
     2     System.out.println("Character... args");
     3 }
     4 
     5 static void F(float f, Character... args) {
     6     System.out.println("Character... args");
     7 }
     8 
     9 public static void main(String[] args) {
    10     F(1,'2');
    11     //F('2','2');//依旧造成歧义!!!!!!!!!!!!!!!!
    12 }

    如果改成这样就是可以的

     1 static void F(char c, Character... args) {
     2     System.out.println("Character... args");
     3 }
     4 
     5 static void F(float f, Character... args) {
     6     System.out.println("Character... args");
     7 }
     8 
     9 public static void main(String[] args) {
    10     F(1,'2');
    11     F('2','2');//完全匹配,调用第一个F
    12 }
  • 相关阅读:
    登录界面
    冲刺一阶段(5月9日)-个人总结07
    冲刺一阶段(5月8日)-个人总结06
    冲刺一阶段(5月7日)-个人总结05
    冲刺一阶段(5月6日)-个人总结04
    冲刺一阶段(5月5日)-个人总结03
    冲刺一阶段(5月4日)-个人总结02
    第一阶段冲刺--个人总结01(忘记发了)
    软件需求分析(补发)
    第八周工作进程表
  • 原文地址:https://www.cnblogs.com/QuentinYo/p/3602045.html
Copyright © 2011-2022 走看看