Java —— static 關鍵字、static 內部類、列舉類
阿新 • • 發佈:2018-12-26
一、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