• 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);
    }
  • 相关阅读:
    修改hive内存限制
    hbase的regionserver宕机
    hbase的regionserver宕机
    根据硬件配置后mapred-site.xml和yarn-site.xml
    根据硬件配置后mapred-site.xml和yarn-site.xml
    阿里RDS备份恢复
    Spring框架(一)
    JVM垃圾回收机制(二)
    JVM垃圾回收机制(一)
    SpringBoot中的入口类SpringApplication
  • 原文地址:https://www.cnblogs.com/zampo/p/4155984.html
Copyright © 2020-2023  润新知