黑马程序员-高新技术-反射

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 

反射就 是把java类中的各种成分映射成相应的java类

 

Constructor

Method

Field

Package等等这些类代表的是字节码文件中的构造函数,字段,方法,包

 

用反射获取构造方法

  

Constructor constructor=String.class.getConstructor(StringBuffer.class);


 

用构造方法获取实例化对象

  String str=(String)constructor.newInstance(new StringBuffer("aaaa"));


 

用Class中的newInstance获取实例化对象

String str1=String.class.newInstance();


 

 

Field

private static void changeStringValue(Object obj)throws Exception {
  // TODO Auto-generated method stub
  Field[] fields = obj.getClass().getFields();
  for (Field field : fields) {

   //在这里用==比较确切,因为字节码文件在内存中只存在一份,所以用==比equals方法更合适
   if(field.getType() ==String.class){
    String oldValue=(String)field.get(obj);
    String newValue=oldValue.replace('b', 'a');
    field.set(obj, newValue);
   }
  }
 }


 

专家模式

谁拥有数据谁就是操作这个数据的专家

Method

  Method methodCharAt=String.class.getMethod("charAt", int.class);
  System.out.println(methodCharAt.invoke(str, 2));


 

invoke方法的第一人参数是对象,如果为null那么这个Method对象对应的是一个静态方法

 

jdk1.4和jdk1.5中invoke方法的区别

在方法中如果有参数是数组,1.5中是可变参数,1.4中是数组

 

在传入的参数是数组时

在1.5中是Object类型的可变参数,而在1.4中是Object类型的数组

如 public static void main(String[] args),要接收的是一个String类型的数组

而public static void main(String... args),要接收的是n个String类型的对象

所以为了兼容1.4

我们在写程序的时候传入参数时,应该传一个数组

而在1.5中编译器会将数组打开以可变参数的形式接收这个数组。

所以在传入一个数组后,编译器会将数组打开,把打开后的每一个元素分别作为一个参数进行操作

这样在1.4中就会出现问题

因为将数组打开后的元素,就不再是这个方法要的参数,程序就会出错

那么我们可以将要传入的数组再封装到一个Object数组中,即mainMethod.invoke(null, new Object[]{new String[]{"111","222","3333"}});

这样在打开这个数组之后,还是一个数组,就可以按照我们的思想把数组传递进去

或者将其转换成Objcet类型的数组,即mainMethod.invoke(null, (Object)new String[]{"111","222","3333"});

这样是把String数组对象转换成了一个Object对象,就是告诉编译器,我传入的是一个对象不是一个数组,不需要打开

 

数组的反射

 

int[] a1=new int[]{1,2,3,4};
  int[] a2=new int[3];
  int[][] a3=new int[2][3];
  String[] a4=new String[]{"a","b","c"};
  System.out.println(a1.getClass()==a2.getClass());
  //System.out.println(a1.getClass()==a3.getClass());
  //System.out.println(a1.getClass()==a4.getClass());
  System.out.println(a1.getClass().getName());
  System.out.println(a3.getClass().getName());
  System.out.println(a4.getClass().getName());
  System.out.println(a1.getClass().getSuperclass().getName());
  System.out.println(a3.getClass().getSuperclass().getName());
  System.out.println(a4.getClass().getSuperclass().getName());
  
  Object aobj1=a1;
  Object aobj2=a3;
  Object aobj3=a4;
  //Object[] aobj4=a1;//基本数据类型不是Object类
  Object[] aobj5=a3;
  Object[] aobj6=a4;
  
  System.out.println(Arrays.asList(a1,a4));
  System.out.println(Arrays.asList(a1));
  System.out.println(Arrays.asList(a4));

 

Array

是对数组进行反射的类

private static void printObject(Object obj) {
  // TODO Auto-generated method stub
  Class clazz=obj.getClass();
  if (clazz.isArray()) {
   int len=Array.getLength(obj);
   System.out.print("[");
   for (int i = 0; i < len; i++) {
    if(i<len-1)
     System.out.print(Array.get(obj, i)+", ");
    else
     System.out.println(Array.get(obj, i)+"]");
   }
  } else {
   System.out.println(obj);
  }
 }


 

 反射的应用

一般在做框架的时候用


package cn.itcast.day1;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;

public class ReflectTest2 {

 /**
  * @param args
  */
 public static void main(String[] args)throws Exception {
  // TODO Auto-generated method stub
  //InputStream ips=new FileInputStream("src/cn/itcast/day1/config.properties");
  //只能读取配置文件
  //InputStream ips=ReflectTest2.class.getClassLoader().getResourceAsStream("resourse/config.properties");
  InputStream ips=ReflectTest2.class.getResourceAsStream("resourse/config.properties");
  Properties props=new Properties();
  props.load(ips);
  ips.close();
  String className=props.getProperty("className");
  Collection collection=(Collection)Class.forName(className).newInstance();
  
  ReflectPoint pt1=new ReflectPoint(3, 5);
  ReflectPoint pt2=new ReflectPoint(3, 3);
  ReflectPoint pt3=new ReflectPoint(3, 3);
  collection.add(pt1);
  collection.add(pt2);
  collection.add(pt3);
  
  System.out.println(collection.size());
  
  
 }

}


 

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值