1. 程式人生 > >Java —— static 關鍵字、static 內部類、列舉類

Java —— static 關鍵字、static 內部類、列舉類

一、static 關鍵字

之前雖然知道靜態方法只能操作靜態變數,但有時寫測試小程式時,main 方法中引用成員變數提示須為靜態的,有點疑惑(忘了最基礎的入口main 方法是靜態的...)。在此,簡單整理下,讓我一次弄個明明白白!

先上結論:

只需記住一點,靜態方法或靜態類只能操作靜態方法或靜態成員屬性(靜態操作靜態),其它情況隨意!

理解含義:

main 方法中能使用的成員屬性必須為靜態的,所以main 或其它靜態方法使用不到的屬性,最好別定義為成員屬性,因為他們並不能被該類直接操作,而是通過該類的其他普通方法操作(當然,普通java 實體類沒此要求)。

測試程式碼:

public class StudyErrorAndException {

	private static String staticVar;
	private String normalVar;
	
	public static void main(String[] args) {
		
		staticMethod();
		normalMethod();//報錯
	}
	
	private static void staticMethod(){
		
		staticVar = "";
		normalVar = "";//報錯
	}
	private void normalMethod(){
		
		staticVar = "";
		normalVar = "";
	}
	
	protected static class InternalStaticClass{
		
		public InternalStaticClass(){
			System.out.println("建立靜態內部類");
			staticVar = "";
			normalVar = "";//報錯,靜態內部類同樣不能操作所屬類的非靜態方法
		}
	}
	protected class InternalNormalClass{
		
		public InternalNormalClass(){
			System.out.println("建立普通內部類");
			staticVar = "";
			normalVar = "";
		}
	}
}

二、靜態內部類

先定義一個基礎靜態內部類:

public class StudyStatic {

	private static int staticVar;
	private static InternalStaticClass innerClass = new InternalStaticClass();
	private static InternalStaticClass innerClass2 = new InternalStaticClass();
	
	public static void main(String[] args) {
		
		System.out.println(innerClass.hashCode());
		System.out.println(innerClass2.hashCode());
	}
	
	protected static class InternalStaticClass{
		
		public InternalStaticClass(){
			
			staticVar++;
			System.out.println(staticVar);
		}
	}
}

列印結果:

1
2
366712642
1829164700
得出結論:

因為靜態內部類只能操作靜態成員屬性,所以無論建立幾次,雖然多個靜態類例項不是同一個(雜湊碼不同),但其操作的變數是共享的(1變為了2)。

意外收穫:

類作為成員屬性時,若宣告時建立,則屬性必需為靜態的才會真正建立,實踐如下:

public class StudyStatic {

	//靜態內部類不會真正建立
	private InternalStaticClass staticC1 = new InternalStaticClass();
	//靜態內部類會真正建立
	private static InternalStaticClass staticC2 = new InternalStaticClass();
	//普通內部類不會真正建立
	private InternalNormalClass normalClass = new InternalNormalClass();
	
	public static void main(String[] args) {
		
	}
	
	protected static class InternalStaticClass{
		
		public InternalStaticClass(){
			
			System.out.println("靜態內部類");
		}
	}
	protected class InternalNormalClass{
		
		public InternalNormalClass(){
			
			System.out.println("普通內部類");
		}
	}
}
提出疑問:

靜態內部類和靜態方法有啥區別?就自己目前理解來看,除了靜態內部類具有類的概念外,與靜態方法的作用沒什麼區別。即靜態方法可能只是完成某一小個功能,而靜態內部類是將某個大的業務抽象為了一個類,更便於管理。

三、enum 列舉型別

enum 列舉型別定義與類定義相似,enum型別本身就相當於類,不過比較特殊,相當於提供了幾個個該類的例項,當然enum型別不能被例項化,但可以修改已經存在的列舉值。

示例程式碼:

public class TestEnum {

	public static void main(String[] args) {
		
		for(int i=0;i<MyEnum.values().length;i++){
			System.out.println(MyEnum.values()[i].getKey()+":"+
					MyEnum.values()[i].getValue());
		}
		MyEnum.Enum1.setKey(4);
		System.out.println(MyEnum.Enum1.getKey()+":"+MyEnum.Enum1.getValue());
	}

	public enum MyEnum{
		
		//多個個列舉值,注意名字並不是構造方法名
		Enum1(1,"One"),Enum2(2,"Two"),Enum3(3,"Three");
		
		//列舉值所包含的屬性
		private int key;
		private String value;
		
		//構造方法
		MyEnum(int key,String value){
			this.setKey(key);
			this.setValue(value);
		}
		public int getKey() {
			return key;
		}
		public void setKey(int key) {
			this.key = key;
		}
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
	}
}
執行結果:
1:One
2:Two
3:Three
4:One
從第4個值可見,列舉值的屬性是可以動態修改的。

要實現列舉功能,可實現Enumeration<T> 介面。該介面提供了兩個方法hasMoreElements() 與nestElement() 方法。

示例程式碼:

import java.util.Enumeration;

public class TestEnum {

	public static void main(String[] args) {
		
		String[] myEnum = {"One","Two","Three","Four","Five"};
		Enumeration<String> e = new MyEnumeration(myEnum);//對於String陣列物件myEnum進行列舉
		while(e.hasMoreElements()){
			System.out.println(e.nextElement());
		}
	}
}

class MyEnumeration implements Enumeration<String>{

	private String[] elements;
	private int index = 0;
	
	public MyEnumeration(){
		elements = null;
	}
	public MyEnumeration(String[] elements){
		this.elements = elements;
	}
	
	@Override
	public boolean hasMoreElements() {
		
		if(index < elements.length){
			return true;
		}else{
			return false;
		}
	}

	@Override
	public String nextElement() {
		
		if(elements!=null){
			index++;
		}
		return elements[index-1];
	}
}
執行結果:
One
Two
Three
Four
Five