疯狂Java讲义(十三)---- 类成员

  • 单例类

  如果一个类始终只能创建一个实例,则这个类被称为单例类。在一些特殊场景下,要求不允许自由创建该类的对象,而只允许为该类创建一个对象。为了避免其他类自由创建该类的实例,把该类的构造器使用private修饰,从而把该类的所有构造器隐藏起来。不过这就需要提供一个public方法作为该类的访问点,用于创建该类的对象,且该方法必须用static修饰(因为调用该方法之前不可能创建出对象,所以调用该方法的不可能是对象,只能是类)。而且,该类还必须缓存已经创建的对象,否则无法知道是否曾经创建国对象,也就无法保证只创建一个对象。为此该类需要使用一个成员变量来保存曾经创建的对象,因为该成员变量需要被静态方法访问,所以该成员变量也必须用static修饰:

  

class Singleton {

    private static Singleton instance;
    private Singleton(){}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        //output :true
        System.out.println(s1 == s2);
    }
}
  • final修饰符

  final修饰field

    final成员变量必须由程序员显式初始化,系统不回队final成员进行隐式初始化。

    final修饰的类Field,实例Field能指定初始值的地方如下:

      类属性:必须在静态初始化块中或声明该属性时指定初始值

      实例属性:必须在非静态初始化块/声明该属性或构造器中指定初始值。

    final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。

 

  final修饰方法

    final修饰的方法不可被重写。

      Objectx类中有个getClass,因为Java不希望重写该方法,所以用final把这个方法密封起来了。

      eg

import java.util.Date;

public class GetClassDemo extends Date {

    public static void main(String[] args) {
        GetClassDemo demo = new GetClassDemo();
        demo.test();

    }

    public void test() {
        System.out.println(super.getClass().getName());
        System.out.println(getClass().getName());
        System.out.println(getClass().getSuperclass().getName());
    }
}

    输出结果:

    com.citi.icg.portal.resource.service.impl.GetClassDemo

    com.citi.icg.portal.resource.service.impl.GetClassDemo
    java.util.Date

    解释:如果在子类中覆盖了父类中的一个方法,那么super.theMethod()会调用父类的theMethod(),而不是子类覆盖后的方法。但如果没有覆盖,那super.theMethod()就调用继承来的theMethod(). 因为getClass()是final修饰的,所以super.getClass()调用的就是Object.getClass()。这个方法返回当前运行时类的Class对象

  •  不可变类

    不可变类的意思是创建该类的实例后,该实例的Field是不可改变的。8个包装类和String类都是不可变的,

    eg

    

class Name {

    private String firstName;

    private String lastName;

    public Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return this.lastName;
    }
}

public class Person {

    private final Name name;

    /*
     * public Person(Name name) { this.name = name; public Name getName() {
     * return name; }
     */

    public Person(Name name) {
        this.name = new Name(name.getFirstName(), name.getLastName());
    }

    public Name getName() {
        return new Name(name.getFirstName(), name.getLastName());
    }

    public static void main(String[] args) {
        Name n = new Name("wukong", "sun");
        Person p = new Person(n);
        System.out.println(p.getName().getFirstName());
        n.setFirstName("bajie");
        System.out.println(p.getName().getFirstName());
    }

}

    如果需要设计一个不可变类,尤其要注意其引用类型Field,如果引用类型Field的雷是可变的,就必须采取必要的措施来保护该Field所引用的对象不会被修改,这样才能创建真正的不可变类。

原文地址:https://www.cnblogs.com/IvySue/p/6306198.html