Java类成员的理解(6.3)

1理解类成员
类成员是属于整个类的,而不是属于对象的。因此创建一个对象时,只会为实例变量分配内存,而不会为类成员变量分配内存,类成员变量是在类初始化时分配的内存(执行main()方法之前),所以当类变量初始化以后,实例变量很可能还没有分配内存,因此类成员是不能访问实例变量的。
Java中对象可以访问类成员变量(很多语言是不允许对象访问类变量的),一般都是通过类来访问对象。

public class NullAccessStatic
{
   private static void test()
   {
      System.out.println("static修饰的类方法");
   }
   public static void main(String[] args)
   {
      // 定义一个NullAccessStatic变量,其值为null
      NullAccessStatic nas = null;
      //使用null对象调用所属类的类方法   
      //下面代码一切正常,可以使用空对象访问类成员,进一步说明类成员是属于类的,其并不在对应实例中   
      nas.test();
   }
}
//注意:如果一个null对象访问实例成员,将会引发NullPointException异常,
//因为null表明该实例根本不存在,既然实例不存在,它的实例成员也就不存在。

2 单例类
大部分时候把类的构造器访问控制权限都定义为public,允许任何类自由创建该类的对象。但在某些时候,允许其他类自由创建该类对象没有任何意义,还可能造成系统性能下降(因为频繁的创建对象,且回收对象会带来系统开销问题),这是就需要引入单例类了。如果一个类始终只能创建一个类,则这个类就被称为单例类。
要实现单例类需要做哪些处理:

  1. 将类的构造器隐藏起来,用private,但又需要创建一个对象,就需要提供一个public方法,用于创建该对象,且该方法必须使用static修饰(因为调用该方法之前还不存在对象,因此调用该方法的只能是类)
  2. 除此之外,还需要缓存已经创建好的对象,否则无法知道曾经是否创建过对象,也就无法保证只创建一个对象。为此该类需要提供一个成员变量来保存曾经创建过的对象,因为该成员变量需要被上面的方法调用,故该成员变量不许用static修饰。
class Singleton
{
   ////使用一个类成员变量来缓存曾经创建过的实例   
   private static Singleton instance;
   //对构造器使用private修饰,隐藏该构造器   
   private Singleton(){}
    // 提供一个静态方法,用于返回Singleton实例
   //该方法可以加入自定义控制,保证指残生一个Singleton对象
   public static Singleton getInstance()
   {
      // 如果instance为null,则表明不曾创建Singleton对象      
      //如果instance不为null,则表明已经创建过Singleton对象
      // 将不会创建新的实例 
      if (instance == null)
      {
        // 创建一个Singleton对象,将其缓存起来           
        instance = new Singleton();
      }
      return instance;
   }
}
public class SingletonTest
{
   public static void main(String[] args)
   {
      //创建Singleton对象不能通过构造器      
      //只能通过getInstance方法来得到实例      
      Singleton s1 = Singleton.getInstance();
      Singleton s2 = Singleton.getInstance();
      System.out.println(s1 == s2); //将输出true
   }
}

由上面代码可以看出,SingletonTest类的main方法中,看到两次产生的Singleton对象实际上就是同一对象。(这就是封装的优势,不允许自由访问类的成员变量和实现细节,而是通过方法来控制合适暴露。表面上是创建了两个对象,实际通过内部处理,实际是同一个对象)

猜你喜欢

转载自blog.csdn.net/qq_43215734/article/details/85259207