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

----------------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 类型(booleanbytecharshortintlongfloatdouble)和关键字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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值