java学习笔记4--对象的初始化与回收

1、对象初始化和回收

对象初始化

系统在生成对象时,会为对象分配内存空间,并自动调用构造方法对实例变量进行初始化

对象回收

对象不再使用时,系统会调用垃圾回收程序将其占用的内存回收

构造方法

  • 一种和类同名的特殊方法
  • 用来初始化对象
  • Java中的每个类都有构造方法,用来初始化该类的一个新的对象
  • 没有定义构造方法的类,系统自动提供默认的构造方法

构造方法的特点

  • 方法名与类名相同
  • 没有返回类型,修饰符void也不能有
  • 通常被声明为公有的(public)
  • 可以有任意多个参数
  • 主要作用是完成对象的初始化工作
  • 不能在程序中显式的调用
  • 在生成一个对象时,系统会自动调用该类的构造方法为新生成的对象初始化

系统提供的默认构造方法

如果在类的声明中没有声明构造方法,则Java编译器会提供一个默认的构造方法;默认的构造方法没有参数,其方法体为空;使用默认的构造方法初始化对象时,如果在类声明中没有给实例变量赋初值,则对象的属性值为零或空

例:声明一个银行帐号类及测试代码

public class BankAccount{
    String  ownerName;
    int    accountNumber;
    float    balance;
}
public class BankTester{
     public static void main(String args[]){
         BankAccount myAccount = new BankAccount();
         System.out.println("ownerName=" + myAccount.ownerName);
         System.out.println("accountNumber=" + myAccount.accountNumber);
         System.out.println("balance=" + myAccount.balance);
    }
}

运行结果:

ownerName=null

accountNumber=0

balance=0.0

自定义构造方法与方法重载

可在生成对象时给构造方法传送初始值,使用希望的值给对象初始化

构造方法可以被重载,构造方法的重载和方法的重载一致

一个类中有两个及以上同名的方法,但参数表不同,这种情况就被称为方法重载。在方法调用时,Java可以通过参数列表的不同来辨别应调用哪一个方法为BankAccount声明一个有三个参数的构造方法

public BankAccount(String initName, int initAccountNumber, float initBalance) {
         ownerName = initName;
         accountNumber = initAccountNumber;
         balance = initBalance;

}

假设一个新帐号的初始余额可以为0,则可增加一个带有两个参数的构造方法

public BankAccount(String initName, int initAccountNumber) {
        ownerName = initName;
        accountNumber = initAccountNumber;
        balance = 0.0f;
}

自定义无参的构造方法

无参的构造方法对其子类的声明很重要。如果在一个类中不存在无参的构造方法,则要求其子类声明时必须声明构造方法,否则在子类对象的初始化时会出错

在声明构造方法时,好的声明习惯是不声明构造方法;如果声明,至少声明一个无参构造方法

构建一个Bush类,有两个有参数的构造方法:

class Bush {
  Bush(int i) {}
  Bush(double d) {}
 }

如果写:new Bush(); 编译器将要告诉你找不到对应的构造方法

说明:

用户在进行类声明时,如果没有声明任何构造方法,系统会赋给此类一个默认(无参)的构造方法。但是,只要用户声明了构造方法,即使没有声明无参的构造方法,系统也不再赋默认的构造方法

例:创建一个拥有两个构造方法的Tree类,一个有参,一个无参。

import java.util.*;
class Tree
{
    int height;
    Tree() {
        prt("Planting a seedling");
        height = 0;
    }
    Tree(int i) {
        prt("Creating new Tree that is "+ i + " feet tall");
        height = i;
    }
    void info() {
        prt("Tree is " + height + " feet tall");
    }
    void info(String s) {
        prt(s + ": Tree is " + height + " feet tall");
    }
    static void prt(String s) {
        System.out.println(s);
    }
} 

测试Tree类:

public class javatest {
    public static void main(String[] args) {
        for(int i = 0; i < 5; i++) {
            Tree t = new Tree(i);
            t.info();
            t.info("overloaded method");
        }
        new Tree();
    }
}

测试结果:

Creating new Tree that is 0 feet tall
Tree is 0 feet tall
overloaded method: Tree is 0 feet tall
Creating new Tree that is 1 feet tall
Tree is 1 feet tall
overloaded method: Tree is 1 feet tall
Creating new Tree that is 2 feet tall
Tree is 2 feet tall
overloaded method: Tree is 2 feet tall
Creating new Tree that is 3 feet tall
Tree is 3 feet tall
overloaded method: Tree is 3 feet tall
Creating new Tree that is 4 feet tall
Tree is 4 feet tall
overloaded method: Tree is 4 feet tall
Planting a seedling

this关键字的使用:

  • 可以使用this关键字在一个构造方法中调用另外的构造方法
  • 代码更简洁,维护起来也更容易
  • 通常用参数个数比较少的构造方法调用参数个数最多的构造方法

使用this关键字,修改BankAccout类中无参数和两参数的构造方法:

public BankAccount() {
        this("", 999999, 0.0f);
}
public BankAccount(String initName, int initAccountNumber) {
        this(initName, initAccountNumber, 0.0f);
}
public BankAccount(String initName, int initAccountNumber, float initBalance) {
         ownerName = initName;
         accountNumber = initAccountNumber;
         balance = initBalance;
}

2、内存回收技术

当一个对象在程序中不再被使用时,就成为一个无用对象,当前的代码段不属于对象的作用域,把对象的引用赋值为空

Java运行时系统通过垃圾收集器周期性地释放无用对象所使用的内存

Java运行时系统会在对对象进行自动垃圾回收前,自动调用对象的finalize()方法

垃圾收集器

自动扫描对象的动态内存区,对不再使用的对象做上标记以进行垃圾回收

作为一个线程运行,通常在系统空闲时异步地执行

当系统的内存用尽或程序中调用System.gc()要求进行垃圾收集时,与系统同步运行

finalize()方法

  • 在类java.lang.Object中声明,因此 Java中的每一个类都有该方法
  • 用于释放系统资源,如关闭打开的文件或socket等
  • 声明格式
protected void finalize() throws throwable

如果一个类需要释放除内存以外的资源,则需在类中重写finalize()方法

应用举例:

对银行帐户类BankAccount进行一系列修改和测试:

  • 声明BankAccount类
  • 声明toString()方法
  • 声明存取款方法
  • 使用DecimalFormat类
  • 声明类方法生成特殊的实例
  • 声明类变量
  • 包括状态、构造方法、get方法及set方法
public class BankAccount{
    private String ownerName;
    private int accountNumber;
    private float balance;
    public BankAccount() {
        this("", 0, 0);
    }
    public BankAccount(String initName, int initAccNum, float initBal) {
        ownerName = initName;
        accountNumber = initAccNum;
        balance = initBal;
    }
    public String getOwnerName()  { return ownerName; }
    public int getAccountNumber() { return accountNumber; }
    public float getBalance()  { return balance; }
    public void setOwnerName(String newName) {
        ownerName = newName;
    }
    public void setAccountNumber(int newNum) {
        accountNumber = newNum;
    }
    public void setBalance(float newBalance) {
        balance = newBalance;
    }
}

声明测试类AccountTester

public class AccountTester {
    public static void main(String args[]) {
        BankAccount anAccount;
        anAccount = new BankAccount("ZhangLi", 100023,0);
        anAccount.setBalance(anAccount.getBalance() + 100);
        System.out.println("Here is the account: " + anAccount);
        System.out.println("Account name: " + anAccount.getOwnerName());
        System.out.println("Account number: " + anAccount.getAccountNumber());
        System.out.println("Balance: $" + anAccount.getBalance());
    }
}

测试结果:

Here is the account: BankAccount@372a1a

Account name: ZhangLi

Account number: 100023

Balance: $100.0

声明toString()方法

将对象的内容转换为字符串

Java的所有类都有一个默认的toString()方法,其方法体如下:

getClass().getName() + '@' +  Integer.toHexString(hashCode())

下面的两行代码等价:

System.out.println(anAccount);
System.out.println(anAccount.toString());

如果需要特殊的转换功能,则需要自己重写toString()方法

toString()方法的几点说明

  • 必须被声明为public
  • 返回类型为String
  • 方法的名称必须为toString,且没有参数
  • 在方法体中不要使用输出方法System.out.println()

为BankAccount类添加自己的toString()方法

public String toString() {
    return("Account #" + accountNumber + " with balance $" + balance);
}
时间: 2024-08-20 01:18:37

java学习笔记4--对象的初始化与回收的相关文章

Java学习笔记之对象与类(1/3)

一.类 类(class)是构造对象的蓝图或模板.由类构造(construct)对象的过程就是创建类的实例(instance)的过程. 封装(encapsulation)是与类有关的一个重要概念.形式上来说,封装是把数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式.对象的数据称为实例域(instance field),操作数据的过程称为方法(method). 继承(inheritance)使得Java中的一个类可以通过拓展另一个类而来.实际上,Java中所有的类都是继承了一个最原始的

Javascript学习笔记之 对象篇(四) : for in 循环_基础知识

先上范例: // Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // prints both bar and moo } 这里我们要注意两点,一是 for in 循环会忽略 enumerable 设置为 false 的属性.例如一个数组的 length 属性.第二是,由于 for in 会遍历整个原型链,所以当原型链过长时,会

Java学习笔记

笔记 本笔记是在看浙大翁恺老师的视频教学时所做,希望对Java初学者有帮助! 一.Java基础1.正确认识Java(1)Java是一种有生产力的OOP语言,C++能做的Java都能做(2)Java与网络关系不大,更不是用来做网页的(3)Java是UNIX世界的产物,具有UNIX的思想(4)Java在国外广泛的被用来做各种应用2.Java历史(1)Brithday:May 23,1995(2)1991:Set-Top box:Jame Gosling(3)1994:OAK and FirstPer

java学习笔记7--Polymorphism

笔记 Polymorphism 多态(polymorphism)也被称为动态绑定『dynamic binding』.后绑定『late binding』或运行时绑定『run-time bingding』.它的意思是要在程序运行的时候,根据对象的类型来决定该绑定哪个方法.多态性是继数据抽象和继承之后的,面向对象的编程语言的第三个基本特性. 绑定(binding): 将方法的调用连到方法本身前绑定(early binding): 当绑定发生在程序运行之前时(就是由编译器或连接器负责)后绑定(late

Java学习笔记,适用于零基础的小伙伴

1. 成员变量与局部变量的区别     1.作用域:         成员变量的作用域是整个类中都可以访问:         局部变量是的作用域是定义它的{}内, {}中的语句执行完它就被回收:     2.初始值:         局部变量使用前必须手动赋值, 系统不会赋默认值:成员变量系统会赋默认初始值.     3.所在内存区域:         局部变量在方法运行的栈内存里,在栈里,会自动释放:         成员变量在对象里,对象在堆里,成员变量也在堆里,不使用的对象会被垃圾回收机制

java教学笔记之对象的创建与销毁_java

本课程的目标是帮你更有效的使用Java.其中讨论了一些高级主题,包括对象的创建.并发.序列化.反射以及其他高级特性.本课程将为你的精通Java的旅程提供指导. 1. 引言 在TIOBE 编程语言排名中,Sun 公司于1995年开发的Java语言是世界上使用最广泛的编程语言之一.作为一种通用编程语言,因为强大的工具包和运行时环境.简单的语法.丰富的平台支持(一次编写,到处运行)以及的异常活跃的社区支持,Java语言对软件开发工程师极具吸引力. 在这一系列的文章中,涵盖了Java相关的高级内容,因此

java学习笔记6--类的继承、Object类

1.类的继承 一种由已有的类创建新类的机制,是面向对象程序设计的基石之一.通过继承,可以根据已有类来定义新类,新类拥有已有类的所有功能 Java只支持单继承,每个子类只能有一个直接父类,父类是所有子类的公共属性及方法的集合,子类则是父类的特殊化,继承机制可以提高程序的抽象程度,提高代码的可重用性 基类(base class),也称超类(superclass),是被直接或间接继承的类 派生类(derived-class),也称子类 (subclass),继承其他类而得到的类,继承所有祖先的状态和行

java学习笔记3--类与对象的基础

1.面向对象的程序设计方法概述 面向对象的程序设计 与结构化程序设计方法相比,更符合人类认识现实世界的思维方式,已成为程序设计的主流方向 涉及的主要概念:抽象.封装.继承.多态 对象 现实世界中:万物皆对象,都具有各自的属性,对外界都呈现各自的行为 程序中:一切都是对象,都具有标识 (identity), 属性和行为(方法),通过一个或多个变量来保存其状态,通过方法(method) 实现他的行为 类 将属性及行为相同或相似的对象归为一类,类可以看成是对象的抽象,代表了此类对象所具有的共有属性和行

java 学习笔记

笔记 JAVA的多线程 一.线程基本概念 将1个程序转换成多个独立运行的子任务.每个子任务都叫做一个线程. "进程"是指一种"自包容"的运行程序.有自己的地址空间.一个进程可以容纳多个同时执行的线程. 事实上,多线程最主要的一个用途就构建1个"反应灵敏"的用户界面. 二.线程的使用 1. 创建一个线程 最简单的方法就是从Thread类继承这个类,包含了创建和运行线程所需的一切东西. Thread最重要的是run方法,继承类必须对之进行重载,使其按