黑马训练营 -------------------------反射

 

----------------------------------- android培训java培训、期待与您交流! -----------------------------------

/**   反射 与 Class类
  * 一 Class类
  *  1:就是java字节码所属的类,字节码就是他的对象
  * 2: 获取字节码的方法
  *  a:Class.forName("Java.util.Date")返回一个字节码,情况一:当内存中已经有了这个类的字节码,情况二:当内存
  *  中不存在时就要去加载了。此种常用类的名字在写的时候不需要知道,
  *  b:类名.class。
  *  c:new String.getClass();
  * 
  * 3:九个Class预定义对象:八个基本数据类型和void类型。
  *
  *二  反射  ————会导致程序性能严重下降
  * 1 :反射就是把java类的各种成分映射成相应的Java类。//我们所得到的是那种成分所对应的对象。
  * @throws NoSuchMethodException
  * @throws SecurityException
  *
  * 2:利用反射创建对象流程
  *   a:  class字节码————Constructor对象——————传入参数
  *  b:  class字节码————new Instance().
  *
  *3: 反射有什么用:实现框架
  *
  *4;数组反射的特点:
  *  a:相同元素类型和相同维度的数组的Class是同一的。
  *  b: 基本类型的一维数组无法转换为Object[],但是能作为Object使用
  *  c:Arrays.toList()处理Int[] 和String的差异
  *  d:无法利用反射去获取一个数组的类型。————只能通过数组元素获取每个元素的类型。
  */
 public static void main(String[] args) throws Exception {
  /*// TODO Auto-generated method stub
  System.out.println(int.class == Integer.class);//false
  System.out.println(int.class == Integer.TYPE);//true   Integer.type返回的是包装类型的字节码
  System.out.println(String.class.isPrimitive());//false
  
*/  
  /*------------------数组的反射和Arrays类  -----------------------*/
  int[] arr1 = {1, 2};
  int[][] arr2 = {{1, 3}, {1}};
  String[] arr3 = {"a", "b"};
  
  //数组转换为Object
  Object obj1 = arr1;
  //Object[] obj2 = arrr1; 无法转换,里面的是int不是Object
  Object obj3   = arr2 ;
  Object[] obj4 = arr2;
  Object obj5  = arr3;
  Object[] obj6 = arr3;
  
  //转换为List,用到了Arrays的
  System.out.println(Arrays.asList(arr1));//[[I@dc8569] 先调用1.4在调用的1.5版本的方法
  System.out.println(Arrays.asList(arr3));//[a, b] 调用的是1.4版本的方法
  // 1.5版本  public static <T> List<T> asList(T... a)
  // 1.4 版本  public static  List asList(Object[]... a)
  
  //获取一个数组的类型
  Object[] obj = new Object[]{1, "AA"};
  Object getObj = obj.getClass();//无法返回具体的类型
  System.out.println(obj[0].getClass());
  System.out.println(obj[1].getClass());
  
/*------------------获取未知类的main方法类(把这个未知类的类名传入dos命令行)  -----------------------*/
  String StringName = args[0];//传入的是一个字符串,只不过恰好为类名
  Method main = Class.forName(StringName).getMethod("main", String[].class);//获取SetingName类的main方法。
  
  /*main.invoke(null, new String[]{"aa", "bb", "cc"}); 此时报 :java.lang.IllegalArgumentException:
   wrong number of arguments,由于1.5版本要兼容1.4版本(把数组中的每个元素当作参数),所以他会对String[]自动拆箱。
    */ 
  main.invoke(null,new Object[]{ new String[]{"aa", "bb", "cc"}});//让他拆
  main.invoke(null, (Object)new String[]{"aa", "bb", "cc"});//不要让他拆
  
/*--------------------------------Methodl类  -----------------------*/
  //当invoke(null,new Object[])时,说明所得到的是静态方法。
  Method method = String.class.getMethod("charAt", int.class);
  char ch =(Character) method.invoke("abc", 2);
  System.out.println(ch);//c   这个按1.5版本,
  System.out.println(method.invoke("abc", new Object[]{2}));//c  这个按1.4版本传入的参数是数组
  
  
/*------------------Field类  字节码身上的变量-----------------------*/
  //查看public 的字段。
  ReflectPoint rp1 = new ReflectPoint(3,5);
  Field fieldY = rp1.getClass().getField("y");//得到这个类的变量y,注:返回的不是对象的变量,而是这个类的变量
  fieldY.get(rp1);//5,
  
  //查看私有的字段
  ReflectPoint rp2 = new ReflectPoint(3,5);
  /*Field fieldX = rp2.getClass().getField("x");//得到这个类的变量y,注:返回的不是对象的变量。
*/      
   Field fieldX = rp2.getClass().getDeclaredField("x");//注意与getField()的区别,这个能够看到私有变量。 
   fieldX.setAccessible(true);//把私有的设置为可以获取。
  int x =(Integer)fieldX.get(rp2);//5, 
  System.out.println(x);
  
/*------------------Constructor 反射应用-----------------------*/
  Constructor c1 = String.class.getConstructor(byte[].class);//得到构造方法String(byte b)的构造方法。
  //用得到的Constructor对象创建对应的String对象。
  c1.newInstance(new byte[]{'a'});
  
  Class[] c = {byte[].class, Charset.class};
  Constructor c2 =String.class.getConstructor(c);//在1.5版本以前按可变的数组传入
  
  
  ReflectPoint rp3 = new ReflectPoint(4,6);
  changeChar(rp3);
  System.out.println(rp3);
 }
 
 /*------实现一个方法跟换掉对象字段中字符串的字符a----*/
 public static void changeChar(Object obj)throws Exception{
  Field[] fields = obj.getClass().getFields();
  
  for(Field field : fields){
   //if(field.getType().equals(String.class));此处由于是同一份字节码所以用equals()语义不对。
   if(field.getType() == (String.class)){
    
    String oldValue = (String)field.get(obj);
    String newValue = oldValue.replace('a', 'p');
    field.set(obj, newValue);//设置新的字段

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值