zoukankan      html  css  js  c++  java
  • 【Java学习笔记】对象生命周期

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    1.创建对象
    1)显示创建:
        a.用new创建对象。
        b.使用反射手段,即调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
        c.调用对象的clone()方法。注意,这种方法不会调用类的构造函数
        d.使用反序列化的方法。
    对于clone方法注意:
    a.Object中的clone方法时protected,若希望对外公开clone()方法,就必须扩大访问范围,改为public
    b.返回Object类型。
    c.若类没有实现Cloneable接口,clone()方法会抛出异常,Object的子类若是允许客户程序调用其clone()方法,那么这个类必须实现Cloneable方法。
    2)隐式创建:
        a.String str= "hello";这种属于String类型直接数对应一个String对象,引用一个String对象。若此时运行String str2=
    "hello";则str和str1是同一个对象。
        b.String中+的使用。
        c.JVM加载一个类的时候,会隐含创建描述这个类的Class实例。
    3)创建步骤:
        a.给对象分配内存。
        b.将对象的实例变量自动初始化为其变量类型的默认值。
        c.初始化对象,给实例变量赋予正确的初始值。
    2.构造方法
    注意:
    没有返回类型(有的话,即使函数名同名也被视为一般函数而非构造方法),不能被static、final、synchronized、abstract和native修饰。
    用this可以重载构造方法:必须在第一条语句使用this。且必须在构造方法中使用this调用其他构造方法。
    在类中没有构造方法的时候JAVA会给每个类一个默认的构造方法,但是若类中显式的添加了构造方法,并且所有的构造方法都带参数,那么这个类除非也显式的定义一个默认构造方法,否则默认的构造方法就缺失了。
    子类的构造方法中,可以通过super语句调用父类的构造方法,因为构造函数是不继承的。例如:super("Something is OK");
    在构建子类对象的时候,JVM首先执行父类的构造方法,然后再执行子类的构造方法。在多级继承的时候,从继承树的最上层的父类开始,依次执行各个类的构造方法。
    构造方法的调用:
    当前类的其他构造方式通过this语句调用它。其子类的构造方法通过super调用。在程序中使用new调用。
    构造方法的访问级别:
    一般的我们的构造方法都是public级别的(以上我们讨论的情况),但是我们现在要讨论的是在private级别的,这就意味着只能在当前类中或在当前类的其他构造方法中通过this语句调用它。当然,在当前类的成员方法中使用new也会调用)
    a.这个类只提供一些静态方法给外部,所以为了禁止外部程序创建类的实例(因为静态方法无需创建实例),所以将构造方法设为private。
    b.禁止这个类被继承。当然是用final也可以解决,但它同时也禁止了外部使用new进行创建实例(同a所述)
    c.这个类需要把构造自身实例的细节封装起来,而向其他程序提供了获得自身实例的静态方法——静态工厂方法。
    3.静态工厂方法:
    假如类需要进一步封装创建自身实例的细节,并且控制自身实例数目,那么可以提供静态工厂方法。
    使用举例:
    public class Gender{
        private String description;
        private static final Gender female = new Gender("female");
        private static final Gender male = new Gender("male");
        private Gender(String description){this.description=description;}
        public static Gender getFemale(){
            return female;
        }
    }
    特点:
    a.静态工厂方法名可以不与类名相同,程序代码可读性增强。比较流行的是将这样的代码命名为valueOf或者getInstance
    b.使用时是否会创建一个新的对象完全取决于方法的实现。
    c.可以返回当前类的子类的实例。
    应用:创建以下各种类。
    a.单例类:系统中具有唯一性的组件。
    实现方法:
    1)把构造方法定义为private类型,提供public static final 类型的静态变量。该变量引用类的唯一的实例。
    2)在方法1)的基础上添加getInstance方法,返回那个静态变量,使用的是静态工厂方法。这个的好处在于可以不修改方法名的前提下修改实现getInstance的实现方式,以适应变更的需求。
    b.自定义枚举类:实例数目有限的类。
    c.不可变类:指创建了这个类的实例后就不允许修改它的属性值。
    创建时把属性定义为private final类型,不对外公开setXXX()方法,只对外公开getXXX()方法。在构造方法中初始化所有属性。覆盖Object的equals()方法和hashCode()方法。若是需要就提供实例缓存和静态工厂方法。
    类的设计优先考虑不可变类。在创建不可变类的时候,若其属性是可变类型,则需要提供保护性拷贝。
    具有实例缓存的不可变类,比如Integer实例,有一个静态工厂方法valueOf(int i),这样创建的一个Integer对象,要是发现前边有值是相同创建好的实例的话,那么直接使用以前创建的。这样的特性可以通过Java集合来作为实例缓存。

    public class Ghost{
        private static final Map<String,Ghost> ghosts = new HashMap<String,Ghost>();
        private final String name;
        private Ghost(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
        public static Ghost getInstance(String name){
            Ghost ghost = ghosts.get(name);
            if(ghost == null){
                ghosts=new Ghost(name);
                ghosts.put(name,ghost);
            }
            return ghost;
        }
        public static void removeInstance(String name){
            ghosts.remove(name);
        }

    在分层的软件系统中,业务逻辑层向客户层提供服务,静态工程类可以进一步削弱这两层间的耦合关系。

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

  • 相关阅读:
    SPOJ 8222 NSUBSTR
    bzoj千题计划284:bzoj2882: 工艺
    bzoj千题计划283:bzoj4516: [Sdoi2016]生成魔咒(后缀数组)
    bzoj千题计划282:bzoj4517: [Sdoi2016]排列计数
    bzoj千题计划281:bzoj4558: [JLoi2016]方
    bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪
    bzoj千题计划279:bzoj4591: [Shoi2015]超能粒子炮·改
    bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机
    bzoj千题计划277:bzoj4513: [Sdoi2016]储能表
    bzoj千题计划276:bzoj4515: [Sdoi2016]游戏
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2843742.html
Copyright © 2011-2022 走看看