您的位置:首页 > 职场人生

黑马程序员_java高新枚举与反射

2012-11-24 09:38 465 查看
----------------android培训java培训、期待与您交流!
----------------
一.枚举是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;

}

}

----------------------
android培训java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: