• 5.3 类成员


    一、理解类成员

    ▲static不要理解为静态的意思,static是类的意思,有static修饰的成员是类成员,没有static修饰的成员是实例变量。

    static不能修饰局部变量,局部变量不属于类成员。

    static不能修饰外部类,外部类不属于类成员。

    类的定义:public(final|abstatct) 类名{...}

    类的成员:成员变量、方法、构造器、内部类、初始化块。static修饰类成员,除了构造器以外,其他类成员都可以修饰。

      类成员属于整个类,当系统第一次准备使用该类的时候,系统会为该类分配内存空间,类变量开始初始化,知道该类被卸载,该类变量所占的内存被GC回收。不管通过类还是对象来访问类成员,实际上都是通过类来访问类成员,同一类所有实例的类变量共享同一块内存区。(为了理解,类成员最好用类来访问)。

      因为类成员属于类,类成员的作用域作用域比实例变量作用域大,完全可能出现类成员已经初始化完成,实例成员还未进行初始化的情况,如果允许类成员来范文实例变量将会引起大量错误。所有static有一条重要的规则:类成员(成员变量、方法、内部类、初始化块(内部枚举枚举))不能访问实例成员(成员变量、方法、构造器、内部类、初始化块(内部枚举枚举))。

     从上图可以看出,有20种情况会报错:无法从静态上下文访问非静态 变量

    1、从类方法访问实例方法

     1 class 面试题1 
     2 {
     3     public void info()
     4     {
     5         System.out.println("这是实例(非静态)方法");
     6     }
     7     public static void main(String[] args) 
     8     {
     9         var p=new 面试题1();//这是实例(非静态)方法
    10         p.info();
    11         info();//面试题1.java:11: 错误: 无法从静态上下文中引用非静态 方法 info()
    12     }
    13 }

    2、从类方法访问非静态内部类

     1 class 面试题2 
     2 {
     3     class A
     4     {
     5         public void info()
     6         {
     7             System.out.println("这是一个非静态的内部类");
     8         }
     9     }
    10     public static void main(String[] args) 
    11     {
    12         A obj=new A();//面试题2.java:12: 错误: 无法从静态上下文中引用非静态 变量 this
    13     }
    14 }

    3、类成员变量访问实例变量

    1 class 面试题3 
    2 {
    3     int a=5;
    4     static int b=a;//面试题3.java:4: 错误: 无法从静态上下文中引用非静态 变量 a
    5 }

    4、静态初始化块访问实例成员

    1 class 面试题4 
    2 {
    3     int age;
    4     static{
    5         age=18;//面试题4.java:5: 错误: 无法从静态上下文中引用非静态 变量 age
    6     }
    7 }

    5、类初始化块调用内部类

    1 class 面试题5 
    2 {
    3     class A
    4     {
    5     }
    6     static{
    7         A obj=new A();//面试题5.java:7: 错误: 无法从静态上下文中引用非静态 变量 this
    8     }
    9 }

    二、单例(Singleton)类

    在某些情况下,允许其他类自由创建该类的对象没有任何意义,还可能造成系统性能下降(因为频繁地创建对象,回收对象带来的系统开销问题),例如只能有一个窗口管理器、一个数据库引擎访问点。

    设计模式:对于一些经常出现的设计场景,前人总结出的一些成功的设计。

    单例模式:在某些场景下,某些类只需创建一个实例。

    如何设计单例模式?

    一、隐藏构造器避免被创建实例

    二、暴露一个static方法用于创建实例

    三、保存实例,记录是否已经创建过实例。

     1 class Singleton 
     2 {
     3     //使用一个类变量来缓存曾经创建过的实例
     4     private static Singleton instance;
     5     //对构造器使用private修饰来隐藏构造器
     6     private Singleton()
     7     {}
     8 
     9     //提供一个静态方法用于创建实例,并且控制只能产生一个实例
    10     public static Singleton getInstance()
    11     {
    12         if(instance==null)
    13         {
    14             //创建一个Singleton对象
    15             instance=new Singleton();
    16         }
    17         return instance;
    18     }
    19 }
    20 
    21 public class SingletonTest
    22 {
    23     public static void main(String[] args)
    24     {
    25         //创建Singleton对象不能调用构造器
    26         Singleton s1=Singleton.getInstance();
    27         Singleton s2=Singleton.getInstance();
    28         System.out.println(s1.equals(s2));
    29     }
    30 }
    31 ---------- 运行Java捕获输出窗 ----------
    32 true
    33 
    34 输出完成 (耗时 0 秒) - 正常终止
  • 相关阅读:
    sublime Text3 常用插件
    No input file specified. nginx服务器报错解决
    has~和belongsTo的区别?
    关于在phpStudy环境下,windows cmd中 php不是内部命令问题
    spring @RequestMapping注解技巧
    VIM快捷键
    Thinkphp5 模块的自动生成
    在php中define和const定义常量的区别
    go语言学习(六)——并发编程
    go语言学习(五)——面向对象编程
  • 原文地址:https://www.cnblogs.com/weststar/p/12398725.html
Copyright © 2020-2023  润新知