一.枚舉是Java SE5.0以後纔有的類型,下面通過一個實例來說明其中的用法
public class TestEnum {
public static void main(String[] args) {
WeekDay wd = WeekDay.FRI;
//枚舉對象的方法
System.out.println(wd.name());
//在枚舉列表中的位置
System.out.println(wd.ordinal());
//枚舉類中的靜態方法
System.out.println(WeekDay.valueOf(“MON“));//返回字字符串參數對應的枚舉
//遍歷枚舉類,
for(WeekDay w : WeekDay.values()){ //靜態方法values()返回一個WeekDay數組
System.out.println(w);
}
}
/* 枚舉也可以象一般的類一樣添加方法和屬性,你可以爲它添加靜態和非靜態的屬性或方法,這一切都象你在一般的類中做的那樣. */
/*還可以有構造方法,但是構造方法必須是私有的即用private修飾*/
public enum WeekDay{
//枚舉列表必須卸載最前面,否則編譯出錯
SUN(1), MON(), TUE, WED, THI, FRI, SAT;
// 構造方法必須是私有的,並且可以在枚舉列表中直接調用
private WeekDay(){
System.out.println(“first”);
}
private WeekDay(int day){
System.out.println(“second”);
}
}
交通燈的一個枚舉類:
public enum TrafficLamp{
RED(30) {
public TrafficLamp nextLamp() {
return GREEN;
}
},
GREEN(45) {
public TrafficLamp nextLamp() {
return YELLOW;
}
},
YELLOW(5) {
public TrafficLamp nextLamp() {
return RED;
}
};
//抽象方法,也可以定義非常想方法
public abstract TrafficLamp nextLamp();
//可以定義屬性變量
private int time;
private TrafficLamp(int time){
this.time = time;
}
}
二 、反射的基石——Class類
Java程序中的各個Java類屬於同一類事物,描述這類事物的Java類就是Class類。
Class類代表一類什麼樣的事物呢?
Person p1 = new Person();
Person p2 = new Person();
Class類的對象代表的是一份字節碼,就是編譯之後的那份類所對應的字節碼。
得到這份字節碼的方式:共有三種
Class cls1 = p1.getClass(); //調用對象的getClass()方法可以得到
Class cls2 =String.class; //用類名.class獲取一個類的字節碼
Class cls3 = Class.forName(“java.util.Date”); //通過Class類的靜態方法forName()獲得
九個預定義類型的實例對象:基本的 Java 類型(boolean
、byte
、char
、short
、int
、long
、float
和double
)和關鍵字void
也表示爲Class
對象。基本類型的字節碼獲取方式只有一種就是類名.class。例如int.class;void.class
數組也是一種Class的實例對象。
總之,只要是在源程序中出現的類型,都有各自的Class實例對象,例如int[],void
三、反射
什麼是反射:反射就是把Java類中的各種成分映射成相應的Java類。例如:一個Java類中用一個Class類的對象來表示,一個類中的組成部分:成員變量,方法,構造方法,包等信息也用一個個的Java類來表示,就像汽車是一個類,汽車中的發動機,變速箱等也是一個個類。表示Java類的Class類顯然要提供一系列的方式,來獲得其中的變量,方法,構造方法,修飾符,包等信息,謝謝信息就是用相應類的實例對象來表示的,它們是:Field、Method、Contrctor、Package等等。
列子:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectTest {
public static void main(String[] args) throws Exception{
String str1 = “abc”;
//三種方式得到Class類,即獲得字節碼
Class cls1 = str1.getClass();//調用對象的getClass()方法
Class cls2 = String.class; //類名.class方式
Class cls3 = Class.forName(“java.lang.String”);//Class類的forName()方法
//驗證得到的是否爲同一份字節碼,輸出結果都爲true
System.out.println(cls1 == cls2);
System.out.println(cls1 == cls3);
//判斷是否爲基本類型的字節碼對象
System.out.println(cls1.isPrimitive());
//基本數據類型的的字節碼獲取只有一種方式,類名.class方式
System.out.println(int.class.isPrimitive());
//數組也是一種特定的類型
System.out.println(int[].class.isPrimitive());//結果爲false
System.out.println(int[].class.isArray());//結果爲true
//構造方法的反射
//Constructor類代表某個類中的一個構造方法
//得到參數類型爲StringBuffer的String的構造方法
Constructor<String> constructor1 = String.class.getConstructor(StringBuffer.class);
//用反射的方式得到new String(new StringBuffer(“abc”))的效果
String str2 = (String)constructor1.newInstance(new StringBuffer(“abc”));
System.out.println(str2.charAt(2));
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField(“y”);//獲取字段,fieldY代表一個變量
//fieldY不是對象身上的變量,而是類上的,要用它去取某個對象上對應的值要調用fieldY的get(obj)方法
System.out.println(fieldY.get(pt1));//結果輸出爲5
//因爲ReflectPoint中的x是private修飾的,無法用fieldX.get(pt1)獲取,這是需要用getDeclareField(“x”);
Field fieldX = pt1.getClass().getDeclaredField(“x”);
//但是由於是私有的,只允許自己訪問,所以還要設置它的訪問權限
fieldX.setAccessible(true);//這種方式一般就稱爲“暴力反射”
System.out.println(fieldX.get(pt1));
changeStringValue(pt1);
System.out.println(pt1.toString());
}
private static void changeStringValue(Object obj) throws Exception{
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
//如果字節碼相同,則替換
if(field.getType() == String.class){
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace(‘b’, ‘a’);
//換取之後要,把新字段設置到對象中去
field.set(obj, newValue);//吧newValue設置到obj對象中
}
}
}
}
用到的RelfectPoint類
public class ReflectPoint {
private int x;
public int y;
public String str1 = “ball”;
public String str2 = “ballball”;
public String str3 = “itcase”;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
//複寫時@Override,你的方法名寫錯了的時候編譯器會自動報錯</span>
@ Override
public String toString(){
return str1+”:”+str2+”:”+str3;
}
}