JAVA静态成员和静态内部类(一)

来源:互联网 发布:淘宝赚取佣金 编辑:程序博客网 时间:2024/05/01 11:48
 静态类(static class)即定义了静态方法,静态变量,静态代码块或者内部静态类的类。这些静态成员不需要实例化即可直接引用。
  • 静态方法:不需要实例化,可直接引用。
  • 静态变量:不需要实例化,可直接引用。
  • 静态代码块:在系统初始化时时使用
  • 静态内部类:不能操作访问外部数据。

静态的类在运行时加载到内存中,不需要实例化,在类的内部也不能使用this。

1. 在类中生命一个方法为static,可以直接点用词方法,而不需要对该类进行实例化,调用格式为“类名.静态方法名”

2.如果在类中定义了静态变量(static field),在类装载时,只分配一块存储空间。也就是说对于该类的所有对象,都是在操作同一块存储空间。示例代码如下:

(1) StaticClass.java文件

Java代码
  1. package com.chensl.staticTest;  
  2. public class StaticClass {  
  3.     public static int i = 0;  
  4.     public static int j = 0;  
  5.     public static void addTest(){  
  6.         i++;  
  7.     }  
  8. }  
package com.chensl.staticTest; public class StaticClass {  public static int i = 0;  public static int j = 0;  public static void addTest(){   i++;  } }   

 

(2)StaticClassTest.java文件

 

Java代码
  1. package com.chensl.staticTest;  
  2. public class StaticClassTest {  
  3.     public static void main(String[] args) {  
  4.         StaticClass sc1,sc2;  
  5.         sc1= new StaticClass();  
  6.         sc2= new StaticClass();  
  7.           
  8.         System.out.println("sc1.i = "+sc1.i+" sc2.i = "+sc2.i);  
  9.         System.out.println("sc1.j = "+sc1.j+" sc2.j = "+sc2.j);  
  10.         sc1.i++;  
  11.         sc1.j--;  
  12.         System.out.println("sc1.i = "+sc1.i+" sc2.i = "+sc2.i);  
  13.         System.out.println("sc1.j = "+sc1.j+" sc2.j = "+sc2.j);  
  14.         System.out.println("StaticClass.i = "+StaticClass.i+" StaticClass.j = "+StaticClass.j);  
  15.   
  16.     }  
  17.   
  18. }  
package com.chensl.staticTest; public class StaticClassTest {  public static void main(String[] args) {   StaticClass sc1,sc2;   sc1= new StaticClass();   sc2= new StaticClass();      System.out.println("sc1.i = "+sc1.i+" sc2.i = "+sc2.i);   System.out.println("sc1.j = "+sc1.j+" sc2.j = "+sc2.j);   sc1.i++;   sc1.j--;   System.out.println("sc1.i = "+sc1.i+" sc2.i = "+sc2.i);   System.out.println("sc1.j = "+sc1.j+" sc2.j = "+sc2.j);   System.out.println("StaticClass.i = "+StaticClass.i+" StaticClass.j = "+StaticClass.j);   }  } 

 

 

 

3.静态代码块

静态代码块有点类似于C中的全局变量的概念,修改上面示例代码如下:

 

(1)StaticJava.java文件

 

Java代码
  1. package com.chensl.staticTest;  
  2.   
  3. public class StaticClass {  
  4.     public static int i = 0;      
  5.     public StaticClass(){  
  6.         i=15;  
  7.     }  
  8.     public StaticClass(int n){  
  9.         i=n;  
  10.     }  
  11.     public static void addTest(){  
  12.         i++;  
  13.     }  
  14. }  
package com.chensl.staticTest;  public class StaticClass {  public static int i = 0;   public StaticClass(){   i=15;  }  public StaticClass(int n){   i=n;  }  public static void addTest(){   i++;  } }

 

(2)StaticJavaTest.java文件

Java代码
  1. package com.chensl.staticTest;  
  2. public class StaticClassTest {  
  3.       
  4.     StaticClass sc=new StaticClass(10);  
  5.     static StaticClass sc1,sc2;  
  6.     //静态代码块在系统启动时自动加载执行  
  7.     static{  
  8.         System.out.println("初始化:sc1.i= "+sc1.i +" sc2.i= "+ sc2.i);  
  9.         sc1 = new StaticClass(27);  
  10.         System.out.println("初始化:sc1.i= "+sc1.i +" sc2.i= "+ sc2.i);  
  11.         sc1 = new StaticClass(15);  
  12.         System.out.println("初始化:sc1.i=  "+sc1.i +" sc2.i= "+ sc2.i);  
  13.     }  
  14.       
  15.     public static void main(String[] args) {  
  16.         // TODO Auto-generated method stub  
  17.         StaticClassTest test = new StaticClassTest();  
  18.         System.out.println("sc1.i= "+sc1.i);  
  19.         System.out.println("sc1.i=  "+sc1.i +" sc2.i= "+ sc2.i);  
  20.         StaticClass.addTest();        
  21.         System.out.println("sc1.i = "+sc1.i+" StaticClass.i = "+StaticClass.i);  
  22.     }  
  23.   
  24. }  
package com.chensl.staticTest; public class StaticClassTest {    StaticClass sc=new StaticClass(10);  static StaticClass sc1,sc2;  //静态代码块在系统启动时自动加载执行  static{   System.out.println("初始化:sc1.i= "+sc1.i +" sc2.i= "+ sc2.i);   sc1 = new StaticClass(27);   System.out.println("初始化:sc1.i= "+sc1.i +" sc2.i= "+ sc2.i);   sc1 = new StaticClass(15);   System.out.println("初始化:sc1.i=  "+sc1.i +" sc2.i= "+ sc2.i);  }    public static void main(String[] args) {   // TODO Auto-generated method stub   StaticClassTest test = new StaticClassTest();   System.out.println("sc1.i= "+sc1.i);   System.out.println("sc1.i=  "+sc1.i +" sc2.i= "+ sc2.i);   StaticClass.addTest();     System.out.println("sc1.i = "+sc1.i+" StaticClass.i = "+StaticClass.i);  }  }

 

 

注,以上有些字段的访问可以不用声明对象,而直接使用静态类名即可

 

 

4.静态内部类

static 不但可以添加到字段、方法、静态模块中,还可以添加到类名称前,将类声明为静态的不过普通类不可以声明为static,只有内部类才可以声明成static,这时,这个声明的静态内部类可以直接使用,而不需要实例化外部类。

使用内部类可以把一个类隐藏在另外一个类的内部,且不需要内部类引用外围类的对象。声明在接口中的内部类,自动成为static和public

简单静态内部类示例:

Java代码
  1. package com.chensl.staticTest;  
  2. public class InnerClassTest {  
  3.     //定义一个内部静态类  
  4.     public static class InnerClass{  
  5.         InnerClass(){  
  6.             System.out.println("InnerClass");  
  7.         }  
  8.         public void print(String string){  
  9.             System.out.println(string);  
  10.         }  
  11.     }  
  12.     public static void main(String[] args) {  
  13.         // TODO Auto-generated method stub  
  14.         //引用静态内部类  
  15.         InnerClassTest.InnerClass IC = new InnerClassTest.InnerClass();  
  16.         IC.print("this is a test");  
  17.     }  
  18. }  
//定义一个内部静态类 public class InnerClassTest {      public static class InnerClass{           InnerClass(){                System.out.println("InnerClass");           }             public void print(String string){             System.out.println(string);        }       }      public static void main(String[] args) {           // TODO Auto-generated method stub   //引用静态内部类           InnerClassTest.InnerClass IC = new InnerClassTest.InnerClass();           IC.print("this is a test");      }  }
 输出结果为:

InnerClass
this is a test

 

 

典型静态内部类范例:计算数组中最小值和最大值的问题。

Java代码
  1. package com.chensl.staticTest;  
  2. /** 
  3.  * This program demonstrates the use of static inner classes. 
  4.  * @version 1.01 2004-02-27 
  5.  * @author Cay Horstmann,添加部分注释by_村夫 
  6.  */  
  7. public class StaticInnerClassTest  
  8. {  
  9.    public static void main(String[] args)  
  10.    {  
  11.       double[] d = new double[20];  
  12.       for (int i = 0; i < d.length; i++){  
  13.          d[i] = 100 * Math.random();  
  14.          System.out.println("d["+i+"]= "+d[i]);  
  15.       }  
  16.       ArrayAlg.Pair p = ArrayAlg.minmax(d);  
  17.       System.out.println("min = " + p.getFirst());  
  18.       System.out.println("max = " + p.getSecond());  
  19.    }  
  20. }  
  21.   
  22. class ArrayAlg  
  23. {  
  24.    /** 
  25.     * 内部静态类,在内部类不需要访问外围对象的时候,应该使用静态内部类, 
  26.     * 有的使用嵌套类(nested class)表示静态内部类 
  27.     * A pair of floating-point numbers 
  28.     */  
  29.    public static class Pair  
  30.    {  
  31.       /** 
  32.        * Constructs a pair from two floating-point numbers 
  33.        * @param f the first number 
  34.        * @param s the second number 
  35.        */  
  36.       public Pair(double f, double s)  
  37.       {  
  38.          first = f;  
  39.          second = s;  
  40.       }  
  41.   
  42.       /** 
  43.        * Returns the first number of the pair 
  44.        * @return the first number 
  45.        */  
  46.       public double getFirst()  
  47.       {  
  48.          return first;  
  49.       }  
  50.   
  51.       /** 
  52.        * Returns the second number of the pair 
  53.        * @return the second number 
  54.        */  
  55.       public double getSecond()  
  56.       {  
  57.          return second;  
  58.       }  
  59.   
  60.       private double first;  
  61.       private double second;  
  62.    }  
  63.   
  64.    /** 
  65.     * 通过使用静态内部类,经过一次遍历,可以找到最大最小值两个结果,并返回。如果只使用方法, 
  66.     * 一次只能返回一个类,所以需要遍历两次数组,才能找到最大值和最小值 
  67.     * Computes both the minimum and the maximum of an array 
  68.     * @param values an array of floating-point numbers 
  69.     * @return a pair whose first element is the minimum and whose second element 
  70.     * is the maximum 
  71.     */  
  72.    public static Pair minmax(double[] values)  
  73.    {  
  74.       double min = Double.MAX_VALUE;  
  75.       double max = Double.MIN_VALUE;  
  76.       for (double v : values)  
  77.       {  
  78.          if (min > v) min = v;  
  79.          if (max < v) max = v;  
  80.       }  
  81.       return new Pair(min, max);  
  82.    }  

私有静态内部类

  1. public class Foo {   
  2.     public static int a;   
  3.     // 私有静态内部类, 只有当有引用时, 该类才会被装载   
  4.     private static class LazyFoo {   
  5.        public static Foo foo = new Foo();   
  6.     }   
  7.   
  8.     public static Foo getInstance() {   
  9.        return LazyFoo.foo;   
  10.     }   
  11. }  
这是一个类级内部类,被修饰成static的类。
// 私有静态内部类, 只有当有引用时, 该类才会被装载
意思是:加载Foo类的时候是不会加载LazyFoo的。只有LazyFoo被引用的时候才会加载这个类。内部类被转载一次static也只被装载一次。

这种方式是结合了懒汉式和饿汉式优点的一种单例模式。