《JAVA笔记 day08 静态_单例》

 1 //static关键字:
 2 
 3 /*
 4 静态方法的使用注意事项:
 5 1,静态方法不能访问非静态的成员。
 6    但是非静态是可以访问静态成员的。
 7    说明:静态的弊端在于访问出现了局限性。好处是可以直接别类名调用。
 8 2,静态方法中不允许出现this,super关键字。
 9 
10 
11 为什么不行呢?
12 原理揭秘:
13 1,静态是随着类的加载就加载了,也是随着类的消失而消失了。
14 2,静态优先于对象存在,被对象共享。
15 3,因为静态先存在于内存中,无法访问后来的对象中的数据。所以静态无法访问
16 非静态,而且内容无法书写this,因为这时对象有可能不存在,this没有任何指向。
17 */
18 class Person
19 {
20     private String name;
21     private int age;
22 
23     Person(String name,int age)
24     {
25         this.name = name;
26         this.age = age;
27     }
28     public /*static*/ void speak()
29     {
30         System.out.println("name="+this.name+",age="+this.age);
31         //sleep();
32     }
33 
34     //定义一个睡觉功能。
35     public static void sleep()
36     {
37         System.out.println(name);
38         System.out.println("睡觉zzzZZZ");
39     }
40 }
41 class  PersonDemo
42 {
43     public static void main(String[] args) 
44     {
45         //Person p = new Person("lisi",20);
46 
47         /*
48         创建对象就是为了产生实例,并进行数据的封装,
49         而调用功能时,却没有用到这些对象中封装的数据。
50         该对象的创建有意义吗?虽然可以编译运行,但是在堆内存中
51         空间较为浪费。
52 
53         不建议创建对象。那么该怎么调用呢?java中的解决方案就是static
54         关键字。
55         被静态static修饰的方法除了可以被对象调用外,还可以被类名调用。
56         静态看上去很好,是不是所有的方法都静态呢?不行!
57 
58         那么什么时候需要将方法定义成静态的呢?
59 
60         定义功能时,如果功能不需要访问类中定义的成员变量(非静态)时,
61         该功能就需要定义成static的。
62         */
63 
64         //p.speak();
65         //p.sleep();
66         Person.sleep();
67     }
68 }

 1 //main函数详解:
 2 /*
 3 静态的主函数:
 4 public static void main(Strng[] args)
 5 
 6 public:权限最大。
 7 static:不需要对象。直接用给定的类名就可以访问该函数了。
 8 void  :不需要返回值。
 9 main  :函数名,该名称是固定的。
10 (String[] args):主函数的参数列表:字符串类型的参数。
11 args  :arguments:参数。该名称就是一个变量名。
12 */
13 class  MainDemo
14 {
15     public static void main(String[] args) 
16     {
17         System.out.println(args);            //[Ljava.lang.String;@2a139a55
18         System.out.println(args.length);    //0
19         System.out.println(args[0]);
20         //show();
21     }
22 
23     public static void show()
24     {
25         System.out.println("show run");
26     }
27 }
 1 //static_静态变量。
 2 /*
 3 静态变量:
 4 什么时候定义静态变量呢?
 5 当该成员变量的值,每个对象都一致时,就把该成员变量定义成static的。
 6 
 7 静态变量和成员变量的区别:
 8 1,所属的范围不同。
 9 静态变量所属与类,成员变量所属与对象。
10 静态变量也成为类变量;成员变量也称为示例变量。
11 
12 2,调用不同。
13 静态变量可以被对象和类调用(一般都用类名调用。)
14 成员变量只能被对象调用。
15 
16 3,加载时间不同。
17 静态变量随着类的加载而加载。
18 成员变量随着对象的加载而加载。
19 
20 4,内存存储区不同。
21 静态变量存储在方法区中。
22 成员变量存储在堆内存中。
23 */
24 class Circle
25 {
26     private double radius;    //圆的半径。
27     private static double pi = 3.14;//每一个圆中都存储一份,浪费内存空间。可以加入静态修饰。
28 
29     Circle(double radius)
30     {
31         this.radius = radius;
32     }
33 
34     //求圆的面积。
35     double getArea()
36     {
37         return radius*radius*/*Circle.*/pi;
38     }
39 }
40 class CircleDemo 
41 {
42     public static void main(String[] args) 
43     {
44         System.out.println("Hello World!");
45     }
46 }
 1 //静态加载的内存图解。
 2 class Circle
 3 {
 4     private double radius;
 5     private static double pi = 3.14;
 6     Circle(double radius)
 7     {
 8         this.radius = radius;
 9     }
10     double getArea()
11     {
12         return radius*radius*pi;
13     }
14     static void show()
15     {
16         System.out.println("circle show run..."+pi);
17     }
18 }
19 class CircleDemo 
20 {
21     public static void main(String[] args) 
22     {
23         Circle.show();
24     }
25 }

 1 //静态代码块
 2 /*
 3 需求:类一加载,需要做一些动作。不一定需要对象。
 4 
 5 //学习目标:必须了解加载的顺序。
 6 静态代码块:
 7         特点:随着类的加载而执行。仅执行一次。
 8         作用:给类进行初始化。
 9 */    
10 
11 class Demo
12 {
13     static int x = 9;//静态变量有两次初始化。一次时默认初始化,一次是显示初始化。
14     static//静态代码块 .在静态变量显示初始化以后再执行。
15     {
16         System.out.println("类加载就执行的部分..."+x);
17     }
18 
19     static void show()
20     {
21         System.out.println("show run.");
22     }
23 }
24 class  staticCodeDemo
25 {
26     public static void main(String[] args) 
27     {
28         Demo.show();//堆内存中没有对象。
29     }
30 }
 1 /*
 2 构造代码块
 3 */
 4 
 5 class Demo
 6 {
 7     int x = 4;//成员变量 1,默认初始化化,2,显示初始化。
 8     {    //构造代码块。只要创建对象就会被调用。给所有对象初始化,而构造函数只给针对的
 9         //对象初始化。这里面可以定义不同构造函数的共性代码。
10         System.out.println("code run,,,"+x);    
11 //        System.out.println("----->haha");
12     }
13     Demo()
14     {
15         System.out.println("demo run");
16         //System.out.println("----->haha");
17     }
18     Demo(int x)
19     {
20         System.out.println("demo run,,,,"+x);
21         //System.out.println("----->haha");
22     }
23 }
24 
25 class ConstructorCodeDemo 
26 {
27     public static void main(String[] args) 
28     {
29         new Demo();//堆内存中有对象。
30         new Demo(5);
31 
32         int x1 = 6;
33         {//局部代码块。作用就是:可以控制局部变量的声明周期。
34             int x = 5;
35             System.out.println("局部代码块..."+x);
36         }
37         System.out.println("over..."+x1);
38     }
39 }
 1 //对象的初始化过程。
 2 class Demo
 3 {
 4     static int x = 1;
 5     int y = 1;
 6 
 7     //静态代码块。
 8     static
 9     {
10         System.out.println("static code run...x="+x);
11     }
12 
13     //构造代码块。
14     {
15         System.out.println("cons code ...y="+y);
16     }
17 
18     //构造函数。
19     Demo()
20     {
21         /*
22         构造函数内的隐式部分。
23         1,super();//访问父类中的构造函数。
24         2,成员变量的显示初始化。
25         3,构造代码块初始化。
26         */
27         System.out.println("cons function ...y="+y);
28     }
29 }
30 class CreateObjectTest
31 {
32     public static void main(String[] args) 
33     {
34         /*
35         对象创建过程,
36         1,加载Demo.class文件进方法区,并进行空间分配。
37         2,如果有静态变量,先默认初始化,再显示初始化。
38         3,如果有静态代码块,要执行,仅执行一次。
39         4,通过new在堆内存中开辟空间,并明确首地址。
40         5,对对象中的属性进行默认初始化。
41         6,调用对应的构造函数进行初始化。    
42         7,构造函数内部:
43             构造函数内的隐式部分。
44             7.1 调用父类的构造函数super();//访问父类中的构造函数。
45             7.2 成员变量的显示初始化。
46             7.3 构造代码块初始化。
47             7.4 构造函数内容自定义内容初始化。、
48         8,对象初始化完毕后,将地址赋值给d引用变量。
49         */
50         Demo d = new Demo();
51     }
52 }

  1 //单例模式
  2 
  3 /*
  4 设计模式:解决某一类问题行之有效的解决办法(思想)。
  5 单例(Singleton):设计模式:
  6 学习设计模式必须先弄清楚它是解决什么问题的。
  7 
  8 单例模式是解决什么问题的?
  9 可以保证一个类的对象唯一性。
 10 
 11 场景:比如多个程序都要使用一个配置文件中的数据,而且要实现
 12       数据共享和交换。必须要将多个数据封装到一个对象中。而且
 13       多个程序操作的是同一个对象。那也就是说必须保证这个配置
 14       文件的唯一性。
 15 
 16 怎么能保证对象的唯一性呢?
 17 1,一个类只要提供了构造函数就可以产生多个对象,
 18   完全无法保证唯一。
 19 既然数量不可控,干脆,不让其他程序建立对象。
 20 
 21 2,不让其他程序创建对象,对像何在?
 22    干脆,自己在本类中创建一个对象,这样好处是什么,可控!.
 23    
 24 3,创建完成后,是不是要给其他程序提供访问的方式。
 25 
 26 怎么实现这个步骤呢?
 27 1,怎么就能不让其他程序创建对象呢?
 28     直接私有化构造函数。不让其他程序创建的对象初始化,这样其他程序就
 29     不能创建对象了,但是在卑劣中还是可以创建本类对象的。
 30 2,直接在本类中new一个本类对象。
 31 3,定义一个功能,其他程序可以通过这个功能获取到本类的对象。
 32 */
 33 //代码体现。
 34 
 35 //【调用方法时,对象已经产生了】
 36 //饿汉式。
 37  class Single
 38 {
 39     //私有化构造函数。
 40     private Single();
 41 
 42     //2,创建一个本类对象。
 43     private static /*finale*/Single s = new Single();//因为getInstance方法是
 44                                     //静态的,所以这个方法只能
 45                                     //访问静态的,所以这里必须
 46                                     //加静态关键字修饰。
 47                                     //因为这个对象s是静态的,可以由其他
 48                                     //程序直接有类名调用,但是这样不安全,
 49                                     //对象不可控,所以为了不让其他程序直接
 50                                     //通过类名的方式来调用,加了private
 51                                     //关键字。
 52 
 53     //3,定义一个方法返回这个对象。
 54     public static Single getInstance(int x)
 55     {
 56         //因为这个方法是要返回一个对象,
 57         //就是为了让其他程序获取这个对象的
 58         //所以这个方法的权限要足够大,所以
 59         //为public的。
 60         if(x<0)
 61             return s;
 62 
 63     }
 64     
 65 }
 66 
 67 //单例的延迟加载方式。(单例:单独的对象)【拿到方法的时候,才产生对象】
 68 //懒汉式。
 69 class Single2
 70 {
 71     private static Single2 s2 = null;
 72 
 73     private Single(){}//私有化构造函数。
 74 
 75     public static Single2 getInstance()
 76     {
 77         if(s2==null)
 78             s2 = new Single2();
 79         return s2;
 80     }
 81 }
 82 
 83 
 84 class SingleDemo
 85 {
 86     public static void main(String[] args) 
 87     {
 88         //要想获取Single的对象,调用geiInstance方法,
 89         //既然无法通过对象调用,只能用类名调用,那么
 90         //这个方法必须是静态的
 91 
 92         Single ss = Single.getInstance();
 93         Single ss2 = Single.getInstance();//ss 和 ss2 指向同一个对象。
 94 
 95 //既然对象s也是静态的,干脆就直接用类名调用不就行了?
 96 //        Single ss = Single.s;//这种方法是可以实现的,加入
 97                              //方法来获取就是为了对象的可控(安全)。
 98 //        Single ss2 = Single.s;
 99     }
100 }
 1 //描述超人。
 2 class SuperMan
 3 {
 4     private String name;
 5 
 6     private static SuperMan man = new SuperMan("克拉克");
 7 
 8     //构造函数私有化。不让其他程序创建本类对象。
 9     private SuperMan(String name)
10     {
11         this.name = name;
12     }
13 
14     //这个方法返回一个本类的对象,给其他程序使用,保证了
15     //对象的唯一性。
16     public static SuperMan getInstance()
17     {
18         return man;
19     }
20 
21     public void setName(String name)
22     {
23         this.name = name;
24     }
25 
26     public String getName()
27     {
28         return this.name;
29     }
30 
31     //一般方法。
32     public void fly()
33     {
34         System.out.println(this.name+"...fly");
35     }
36 }
37 class SingleDemo
38 {
39     public static void main(String[] args) 
40     {
41         //超人对象应该是唯一的。保证superMan的唯一性。
42         //可以使用单例模式解决问题。
43         //SuperMan man = new SuperMan("克拉克");
44 
45         SuperMan man1 = SuperMan.getInstance();
46         SuperMan man2 = SuperMan.getInstance();
47         man1.setName("英雄");
48         man2.fly();//输出:英雄...fly  说明man1,和man2指向的是同一个
49                     //对象。
50     }
51 }
原文地址:https://www.cnblogs.com/sun-/p/5324158.html