JAVA基础之初始化与清理

来源:互联网 发布:淘宝宝贝失效还能买吗 编辑:程序博客网 时间:2024/06/02 04:07

用构造器确保初始化

构造器与类名称相同;是一种特殊类型的方法,因为它没有返回值。
在创建对象时,会为对象分配存储空间,并调用相应的构造器。
不包含任何参数的构造器叫做默认构造器

方法重载

class Person {    public Person() {}    public Person(String name){}    public Person(String name,int age){}}
  • 区分重载
每个方法都有独一无二的参数类型列表
  • 方法重载
1.如果传入的数据类型小于方法中声明的形式参数类型,实际数据类型就会被提升; char略有不同,如果无法找到恰好接受char参数的方法,就会把char直接提升至int型
2.如果传入的实际参数大于重载方法声明的形式参数,就需要进行强制转换,否则编译器就会报错。eg:void test(byte b) {}int i = 5;test(i);//编译器会报错

缺省构造器

默认构造器又名“无参”构造器,是没有形式参数的。
如果类中没有构造器,编译器会自动帮你创建一个默认构造器。
  • 作用
用于创建一个“默认对象”

this关键字

this关键字只能在方法内部使用,表示对“对调用方法的那个对象”的引用
如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可
class Test {    private Test(){}    public Test newInstance() {        return this;    }}
  • 在构造器中调用构造器
class Test {    String s;    public Test(){this("test");}    public Test(String s){this.s = s;}}
构造器中只能用this调用一个构造器,并且必须置于初始处
除构造器外,编译器禁止其他方法调用构造器
  • static的含义
可以通过类本身来调用static方法,也可以通过对象来调用
static方法就是没有this的方法
在static方法内部不能调用非静态方法,反过来是可以的。

清理:终结处理和垃圾回收

java垃圾回收器负责回收无用对象占据的内存资源
垃圾回收器只知道释放那些经由new分配的内存
  • finalize()的用途何在
一旦垃圾回收器准备好释放对象占用的储存空间,将首先调用其finalize(),并且在下一次垃圾回收动作发送时,才会真正回收对象占用的内存
无论是“垃圾回收”还是“终结”,都不保证一定会发生。如果java虚拟机(JVM)并未面临内存耗尽的情形,它是不会浪费时间去执行垃圾回收以恢复内存的。
System.gc()用于强制进行终结动作
Java虚拟机采用一种自适应的垃圾回收技术。
  • 自适应技术
标记-清扫:从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活的对象,就会给对象设一个标记,这个过程中不会回收任何对象。只有全部标记工作完成的时候,清理动作才会开始。在清理过程中,没有标记的对象将被释放,不会发生任何复制动作。停止-复制:先暂停程序的运行,然后将所有的存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾。“标记-清扫”与“停止-复制”都是在程序暂停的情况下才能进行。Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”方式;同样,Java虚拟机会跟踪“标记-清扫”效果,要是堆空间出现很多碎片,就会切换回“停止-复制”方式
  • 注意
1.对象可能不被垃圾回收2.垃圾回收并不等于“析构”3.垃圾回收只与内容有关

成员初始化

方法的局部变量没有初始化就会编译出错
  • 默认初始化
类的数据成员没有初始化就会被赋予默认初始值boolean:falsechar:0(空白)byte,short,int,long:0float,double:0.0对象:null
  • 指定初始化(自动初始化)
在定义类成员变量的地方为其赋值
class Test {    int i = 10; //方式1    int j = getNum(i); //方式2    private int getNum(int i) {        return i * 10;    }}

构造器初始化

在运行时刻,可以调用方法或执行某些动作来确定初值
无法阻止自动初始化的进行,它将在构造器被调用之前发生
  • 静态数据的初始化
static关键字不能应用于局部变量,无论创建多少个对象,静态数据都只占一份存储区域静态初始化只有在必要时刻才会进行,静态初始化只在Class对象首次加载的时候进行一次
  • 对象的创建过程

假设有个类为Dog

1.首次创建Dog对象(或Dog的静态方法/静态域首次被访问)时,编译器首先会找到Dog.class文件2.载入Dog.class,执行所有有关静态初始化的动作3.使用new Dog()创建对象时,首先在堆上为Dog对象分配足够的存储空间4.这块存储空间会被清零,将Dog对象中所有基本类型数据设置成默认值(默认初始化),设置引用为null5.执行所有出现与字段定义处的初始化动作(指定初始化)6.执行构造器
  • 初始化顺序
变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
//当new Hello()时,对象创建顺序依次为t1,t2,t3,t4,t5,t6//静态对象 - 静态代码块初始化 - 显示初始化 - 构造代码块初始化 - 构造函数初始化class Test {    public Test(int marker) {        System.out.println("Test(" + marker + ")");    }}class Hello {    static Test t1 = new Test(1);    Test t3 = new Test(3);    Test t4;    Test t5;    static {        //静态代码块,只执行1次        Test t2 = new Test(2);    }    {        //构造代码块,先于构造器初始化,无论调用哪个构造函数,都会执行该初始化        t4 = new Test(4);    }    public Hello() {        t5 = new Test(5);        Test t6 = new Test(6);    }}

数组初始化

  • 定义数组
类型后加[],如int[] i;或int i[];
  • 数组初始化
int[] i = {1,2,3};Integer[] a = new Integer[]{new Integer(1),2,new Integer(3)};
int[] j = new int[10];
Random rand = new Random();int[] a = new int[rand.nextInt(20)];
Object[] obj = new Object[]{new Integer(1),new Float(2.0),new Double(3.0)};Object[] objects = new Integer[]{1,2,3};
  • 可变参数列表
class Test {    public static void main(String[] args) {        Test test = new Test();        test.printArray(1, new String("Hello"), new Float(2.0));        test.printArray(2, (Object[])new String[] {"Hello","World"});        test.printArray(0);    }    public void printArray(int num, Object... objects) {        System.out.print(num + " ");        for (Object object : objects) {            System.out.print(object + " ");        }        System.out.println();    }}

枚举类型

由于枚举类型的实例是常量,按照命名惯例都用大写字母表示
枚举类型可以在switch语句内使用
class Test {    public enum Animal {        PIG, DOG, SHEEP, DUCK, WOLF    }    public static void main(String[] args) {        for (Animal animal : Animal.values()) {            System.out.println(animal.ordinal() + " : " + animal);        }        Animal animal = Animal.PIG;        System.out.print(animal);    }}
0 0
原创粉丝点击