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 秒) - 正常终止

猜你喜欢

转载自www.cnblogs.com/weststar/p/12398725.html
5.3