Java基础之静态修饰符知识点总结

来源:互联网 发布:工商网络监管 编辑:程序博客网 时间:2024/06/05 06:44
静态修饰的特点static是一个修饰符,用于修饰成员(成员变量和成员函数)。   1,静态成员随着类的加载而加载。   2,静态成员优先于对象存在。   3,静态成员被所有对象所共享   4,静态成员中多了一个调用方式,可以被类名直接调用。静态使用的注意事项   1,静态方法只能访问静态成员。       非静态方法既可以访问静态又可以访问非静态。   2,静态方法中不可以定义this,super关键字。       因为this代表是对象。而静态存在时,有可能没有对象。所以静态方法运行时,this是没有任何对象代表的。       简单说,先进内存的数据不可以访问后进内存的数据,可是后进内存数据可以访问先进内存的数据。   3,主函数是静态的。静态:    好处:静态成员多了一种调用方式。可以直接被类名调用     格式 :类名.静态成员。也可以被对象调用。    弊端:静态方法只能访问静态成员,出现了访问局限性。    静态修饰的数据对象共享的数据,存放在方法区的静态区中。    非静态的数据,是每一个对象特有数据。存放在对象的所属的堆内存中。
例子1:静态修饰符static的用法实例。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. class Person{  
  3.     String name;  
  4.      static String country = "CN";  
  5.     public static void show(){  
  6.         System.out.println("country="+country);  
  7.     }  
  8. }  
  9. public class StaticDemo {  
  10.     public static void main(String[] args) {  
  11.          //静态成员多了一种调用方式。直接可以被类名所调用。  
  12.         Person.show();  
  13.         Person p = new Person();  
  14.         p.name="zhangsan";  
  15.         System.out.println(p.name);  
  16.         Person p2 = new Person();  
  17.         p2.name="lisi";  
  18.         System.out.println(p2.name);  
  19.     }  
  20. }  
当成员变量被静态修饰后。静态成员变量和非静态成员变量的区别:  1,静态变量也称为类变量,也就是直接可以被类名调用的变量。这个变量是所属于类的。       非静态变量成为成员变量,或者实例变量,是被对象调用的,是所属具体对象的。  2,静态变量随着类的加载而加载,也意味着随着类的消失而消失。生命周期最长。       实例变量,随着对象的创建而加载,随着对象的消失而消失。按照对象的生命周期而存在。  3,静态变量存储在方法区的静态区中。       实例变量存在于对象所属的堆内存中。   4,静态变量数据,被所有对象所共享。       实例变量是对象中的特有数据。任何成员被访问使用,必须要被调用。如果是非静态成员,必须要被对象调用。在本类中调用是使用的是this。如果是静态成员,必须要被类名调用。只不过在书写时,可以省略。静态变量在静态区中也会进行默认初始化。
例子2:静态成员的调用方式。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. class Demo{  
  3.     int num1 = 3;  
  4.     static int num2 = 5;  
  5.     void show(){  
  6.         System.out.println("num1="+this.num1);  
  7.         System.out.println("num2="+Demo.num2);  
  8.     }  
  9.     static void method(){  
  10.         System.out.println("num2="+Demo.num2);  
  11.     }  
  12. }  
  13. public class StaticDemo2 {  
  14.     public static void main(String[] args) {  
  15.         Demo d = new Demo();  
  16.         d.show();  
  17.         d.method();  
  18.         System.out.println("------------");  
  19.         Demo.method();  
  20.     }  
  21. }  
什么时候使用static呢?成员变量:    什么时候被静态修饰呢?    当该成员变量所存储的数据,每一个对象都是一样的,这时没有必要把该数据存储到每一个对象中,只要让所有对象共享该数据即可,这时成员就需要被static修饰。当数据需要被对象共享时,就使用static修饰。这样可以对共享的数据节约内存。成员函数:    当成员函数内并没有访问对象中的特有数据时,就将该方法定义成静态的。    简单说:该函数如果访问了成员变量,该函数就是非静态的。该函数没有访问过成员变量,或者访问过静态的成员变量,那么为了程序的严谨性,将该方法定义成静态的。因为该方法不需要对象存在,既可以使用。
例子3:定义静态成员函数的实例演示。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. class Person1{  
  3.     String name;  
  4.     static String country = "CN";  
  5.     Person1(String name){  
  6.         this.name = name;  
  7.     }  
  8.     public void show(){  
  9.         System.out.println("name="+this.name);  
  10.     }  
  11.     public static void method(){  
  12.         System.out.println("country="+Person1.country);  
  13.     }  
  14. }  
  15. public class StaticDemo3 {  
  16.     public static void main(String[] args) {  
  17.         Person1 p1 = new Person1("aa");  
  18.         p1.show();  
  19.         Person1 p2= new Person1("bb");  
  20.         p2.show();  
  21.         Person1.method();  
  22.     }  
  23. }  
例子4:静态函数的实例演示。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. /*  其中的每一个功能都没有对该类的对象的特有数据进行访问, 
  3.     那么这些功能,就不需要对象调用。除了对象调用方式外, 
  4.     还有一个类名调用方式。所以可以将这些功能都定义成static的。 
  5.         这个类中的功能都被静态化后,只要使用类名调用即可。 
  6.      
  7.     但是其他程序在使用该类时,因为该类中有一个默认的构造函数, 
  8.     所以其他程序还可以建立该类对象,而该类并不需要对象就可以 
  9.     使用类中的成员。所以这个对象建立是没有意义的。为了提高程 
  10.     序的严谨性。应该强制不让其他程序建立该类对象。 
  11.      
  12.     当该类中的属性或者行为都是静态的时候,该类创建对象是非常没有意义的。 
  13.     所以就要强制不让其他程序建立对象,也就是将该类的构造函数私有化。 
  14.     这样,你即使建立了该类对象,也没有办法初始化。 
  15.      */  
  16. public class ArrayTool {  
  17.     private ArrayTool(){}  //不让其他的程序创建该类文件  
  18.     //对int类型的数组进行排序。从小到大。  
  19.     public static void sort(int[] arr){  
  20.         for(int x = 0;x<arr.length-1;x++){  
  21.             for(int y = x+1;y<arr.length;y++){  
  22.                 if(arr[x]>arr[y]){  
  23.                     swap(arr,x,y);  
  24.                 }  
  25.             }  
  26.         }  
  27.     }  
  28.        //给数组进行换位操作。  
  29.     private static void swap(int[] arr, int x, int y) {  
  30.         int temp = arr[x];  
  31.         arr[x] = arr[y];  
  32.         arr[y]=temp;  
  33.     }  
  34.     //将int数组转换成字符串。  
  35.     public static String arrToString(int[] arr){  
  36.         String str="[";  
  37.         for(int x = 0;x<arr.length;x++){  
  38.             if(x!=arr.length-1){  
  39.                 str=str+arr[x]+",";  
  40.             }else {  
  41.                 str = str+arr[x]+"]";  
  42.             }  
  43.         }  
  44.         return str;  
  45.     }  
  46.     //获取数组中的最大值。  
  47.     public static int getMax(int[] arr){  
  48.         int max=0;  
  49.         for(int x = 1;x<arr.length;x++){  
  50.             if(arr[x]>arr[max]){  
  51.                 max =x;  
  52.             }  
  53.         }  
  54.         return arr[max];  
  55.     }  
  56. }  
  57. ---------------------------------  
  58. package cn.itheima.day18;  
  59. public class ArrayToolDemo {  
  60.     public static void main(String[] args) {  
  61.         int[] arr = {3,1,4,5};  
  62.         String str1 = ArrayTool.arrToString(arr);  
  63.         System.out.println(str1);  
  64.         ArrayTool.sort(arr);  
  65.         String str = ArrayTool.arrToString(arr);  
  66.         System.out.println(str);  
  67.     }  
  68. }  
主函数静态的,说明主函数只能直接访问静态的成员。   public static void main(String[] args)    public: jvm调用的函数必须权限足够大。所以被public修饰。   static: 主函数随着类的加载而加载,jvm不需要创建该类对象既可以完成对该函数的调用,所以是静态的。   void: 主函数没有返回值。   main: 函数名,是固定的,jvm认识。   (String[]args):主函数的参数列表,参数类型是:一个字符串数组类型的参数。   args:参数名称。  主函数有参数,那么jvm调用的时候,就需要传入相对应的实际参数。问:jvm调用主函数时,到底传入了什么呢?//System.out.println(args);//[Ljava.lang.String;@de6ced//[Ljava.lang.String;@de6ced:通过这个结果看到,args指向了一个具体的数组实体。//而且该数组中的元素是String类型的。        System.out.println(args.length);//0//通过两个输出语句,就可以验证,jvm给主函数传递的实际参数是: new String[0];这是jvm传入的默认值。但是没什么用,所以我们在使用main时,可以自定义该主函数数组中的元素。
例子5:主函数分析的实例演示。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. public class MainDemo {  
  3.     int x = 4;  
  4.     public static void main(String[] args) {  
  5.         //System.out.println(args);//[Ljava.lang.String;@de6ced  
  6.         //[Ljava.lang.String;@de6ced:通过这个结果看到,args指向了一个具体的数组实体。  
  7.         //而且该数组中的元素是String类型的。  
  8.                   
  9.         System.out.println(args.length);//0  
  10.         //通过两个输出语句,就可以验证,jvm给主函数传递的实际参数是: new String[0];  
  11.         /* 
  12.         这是jvm传入的默认值。 
  13.         但是没什么用,所以我们在使用main时,可以自定义该主函数数组中的元素。 
  14.         */  
  15.          String arr[]={"haha","hehe","heihei","xixi"};  
  16.          new MainDemo().show();  
  17.          Test.main(arr);  
  18.     }  
  19.     public void show(){  
  20.         System.out.println("x="+x);  
  21.     }  
  22. }  
  23. class Test{  
  24.     public static void main(String[] args){  
  25.         for(int a=0;a<args.length;a++){  
  26.             System.out.println(args[a]);  
  27.         }  
  28.     }  
  29. }  
静态代码块。格式:static{    code..;}     作用:当类在加载进内存时,如果需要进行一些内容的执行,完成一个类的初始化。就需要使用静态代码块来完成,给类进行初始化。   执行特点:当类被加载时,静态代码就执行了,而且只执行一次。而且优先于main函数执行。
例子6:静态代码块的实例演示。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. //运行顺序:静态代码块--->构造代码块--->构造函数  
  3. class StaticCode{  
  4.     {   //静态代码块  
  5.         System.out.println("AAAAA");  
  6.     }  
  7.     static{   //静态代码块  
  8.         System.out.println("a");  
  9.     }  
  10.     public StaticCode() {  
  11.         System.out.println("StaticCode");  
  12.     }  
  13.     static void show(){  
  14.         System.out.println("show run");  
  15.     }  
  16. }  
  17. public class StaticCodeDemo {  
  18.     static {  
  19.         System.out.println("b");  
  20.     }  
  21.     public static void main(String[] args) {  
  22.         System.out.println("d");  
  23.         //StaticCode.show();  
  24.         new StaticCode();  
  25.         System.out.println("e");  
  26.     }  
  27.     static{  
  28.         System.out.println("c");  
  29.     }  
  30. }  
  31. //打印结果:  
  32. /* 
  33.   * b  c  d  a  AAAAA  StaticCode  e 
  34.  */  
设计模式:就是解决某类问题最行之有效的解决方案,设计模式是一种思想。java中总结出来23种设计模式。单例设计模式(23种设计模式之一):    解决的问题:保证一个类在内存中的只存在一个对象。    简单说:保证一类在内存中的对象唯一性。    应用场景:比如配置文件。A要使用配置文件对象。B程序也要使用配置文件对象。希望A程序对配置数据修改后,B程序可以直接使用,那么就需要A程序,和B程序使用的同一个对象.如何保证一个类在内存中的对象唯一性呢?    1)为了控制该类的对象建立,不让其他程序建立该类的对象。    2)在本类中自定义一个本类对象。    3)对外提供获取该对象的方式即可。代码如何实现呢?    1)可以将构造函数私有化。这样对方程序创建就无法初始化。已达到不允许,其他程序创建对象的目的。    2)在本类中,通过new创建一个本类对象。    3)提供一个公共的方法返回该对象,方便于其他程序获取该对象。代码体现具体:    1)私有化构造函数。    2)创建一个私有并静态的本类的对象。    3)创建一个公共的static方法返回该对象。
例子7:单例模式的实例演示。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. //饿汉式  
  3. class Single{  
  4.     private static Single s = new Single();  
  5.     private Single(){}  
  6.     public static Single getInstance(){  
  7.         return s;  
  8.     }  
  9. }  
  10. //需要保证Demo类在内存中的对象唯一性。只要保证一个类的对象唯一性  
  11. class Demo3{  
  12.     private int num = 4;  
  13.     private static Demo3 d = new Demo3();//类一加载,该对象就已经存在了。  
  14.     private Demo3(){}  
  15.     public static Demo3 getInstance(){  
  16.         return d;  
  17.     }  
  18.     public int getNum() {  
  19.         return num;  
  20.     }  
  21.     public void setNum(int num) {  
  22.         this.num = num;  
  23.     }  
  24. }  
  25. public class SingleDemo {  
  26.     public static void main(String[] args) {  
  27.         /*Single ss = Single.getInstance(); 
  28.         Single ss1 = Single.getInstance(); 
  29.         System.out.println(ss==ss1);*/  
  30.         Demo3 d1 = Demo3.getInstance();  
  31.         Demo3 d2 = Demo3.getInstance();  
  32.         d1.setNum(10);  
  33.         d2.setNum(20);  
  34.         System.out.println("d1.num="+d1.getNum());  
  35.         System.out.println("d2.num="+d2.getNum());  
  36.     }  
  37. }  
对象的延迟加载方式。这种方式看上去很美,但是当并发访问getInstance方法时,容易出现安全隐患(线程安全问题)懒汉式
例子8:单例设计模式(懒汉式)的实例演示。
[java] view plain copy
  1. package cn.itheima.day18;  
  2. //饿汉式  
  3. class Single1{  
  4.     private static Single1 s = null;  
  5.     private Single1(){}  
  6.     public static Single1 getInstance(){  
  7.         if(s==null){  
  8.             s =  new Single1();  
  9.         }  
  10.         return s;  
  11.     }  
  12. }  
  13. public class SingleDemo1 {  
  14.     public static void main(String[] args) {  
  15.         Single1 ss = Single1.getInstance();  
  16.         Single1 ss1 = Single1.getInstance();  
  17.         System.out.println(ss==ss1);  
  18.     }  
  19. }  
使用时,一般使用饿汉式。而面试时,都面试懒汉式,因为涉及的技术细节很多。面向常见问法:请写出一个单例延迟加载的示例。这个考的就是懒汉式.
原创粉丝点击