黑马程序员-Java基础加强之反射

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

黑马程序员-java反射机制

java反射机制
1.首先随便写了一个类,再通过反射来调用这个类的方法
public class Dog {
 public String name;
 private int age;
 public String bite(String name,int age){
  return "bite the person named" + name +" "+ age +" yeas old!";
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}
2.然后通过反射来调用上面类的bite 方法
public class TestGetMethod {
 public static void main(String[] args) throws Exception {
 String clasString  = "classTest.Dog";
  Class<?> class1 = Class.forName(clasString); //返回一个Dog 对象
  Object obj = class1.newInstance();//返回一个对象的实例
  
  Class arg[] = new Class[]{String.class,int.class};
  Method bite = class1.getMethod("bite", arg);//根据方法名称、参数类型返回指定的方法
  
  Object obj1[] = new Object[]{new String("peter"),new Integer(23)};
  System.out.println(bite.invoke(obj, obj1));//根据传入的参数调用方法
 }
}
3.执行上面的方法后输出:
bite the person namedpeter 23 yeas old!








一、分析
   比如:Person有什么那?姓名,身高,睡觉行为等;而Class用于描述java的类,那有什么那?类名,所属包名,成员变量,成员方法等;Class类没有构造方法,它对应的是个各类的字节码文件,也就是.class文件,同理就是说,每一个类的字节码,都是Class类的实例对象;Person的字节码是Class类的实例对象;Person.class就表示Person在内存中的字节码Date的字节码同样也是Class类的实例对象;Date.class
   一》得到各个字节码对应的实例对象(Class类型)三种方法
   1.类名.class;如:System.class;
   2.对象.getClass();如:new Date().getClass();前提必须由对象名;
   3.Class.forName(“类名”);如;Class.forName(“java.util.Date”);
   Class的静态方法forName();指定类的完整名称;
   返回字节码文件。
   反射用的通常是这种方式:因为写源程序的时候还不知道类的名字;
   通常用一个变量表示;
   二》有九个预定义的class对象,8个基本数据类型,1个void.class
   三》
  String s = "abc";
  Class cls1 = s.getClass();
  Class cls2 = String.class;
  Class cls3 = Class.forName("java.lang.String");
  //因为内存中只有一份字节码,所以不管用那种方式创建,都相等;
  System.out.println(cls1 == cls2);
  System.out.println(cls1 == cls3);
二、构造方法的反射应用(Constructor类):getConstructor()
  一、得到某个类的所有构造函数:所有的构造方法会装到一个数组里面;
  Constructor[] constructors = Class.forName(“java.lang.String”).getConstructors();
  二、getConstructor()得到某一个构造方法,构造方法那么多,得到的具体是哪一个那?
  就要根据参数类型,参数类型用class对象表示
  Constructor cons1 =
  String.class.getConstructor(StringBuffer.class ,int.class);
  就是表示得到String类中,参数为StringBuffer和int的构造方法;
  三、Constructor类中有一个newInstance()方法,根据构造方法创建实例对象;
  String str = (String)cons1.newInstance(new StringBuffer("abc"));
  四、上面是利用String有参数的构造函数创建对象,其实Class类给我们提供了一个创建对象的方法newInstance(),但是这个方法只能调用无参数的构造方法,比较方便,
  String s=(String)Class.forName(“java.lang.String”).newInstance();
  同样也创建了一个String对象;
三、成员变量的反射(Field类)getField()
  public class ReflectPoint {
   private int x;
   public int y;
   public ReflectPoint(int x, int y) {
   super();
   this.x = x;
   this.y = y;
   }
  }
  ReflectPoint pt1 = new ReflectPoint(3,5);
  
    //利用反射得到成员Y,用Filed类,先得到该类的字节码。
  //然后得到字节码中的成员变量。
  Field fieldY = pt1.getClass().getField("y");
  
    //fieldY的值是多少那?5,错,fieldY对应的是该类的字节码中变量y
  //fieldY不是对象身上的变量,而是类上,
  //要用它去取某个对象上的值;
  System.out.println(fieldY);
  System.out.println(fieldY.get(pt1));
  
    //获取x变量,因为x是私有的,java中定义了专用的方法
  //反射获取私有变量getDeclaredField();
  Field fieldX = pt1.getClass().getDeclaredField("x");
  
    //前面已经获取,下面设置访问私有变量;
  //强制访问,setAccessible(true)不能省略,否则运行失败,不让访问私有变量
  fieldX.setAccessible(true);
  System.out.println(fieldX.get(pt1));
  
    ..应用一下:
  //将任意个对象中的所有String类型的成员变量所对应
  //的字符串内容的“b”替换“a”;
  public static void changeStringValue(Object obj)throws Exception
  {
   //获取字节码中所有的成员变量
   Field[] fields = obj.getClass().getFields();
   for(Field field : fields)
   {
   //遍历是否是String类型变量
   //这里应该用==号,而不是equals,因为只有一份String字节码,他们用的都是同一分
   if(field.getType() == String.class)
   {
   String oldValue = (String)field.get(obj);
   //将b替换成a
   String newValue = oldValue.replace("b", "a");
   //把新值set给对象
   field.set(obj, newValue);
   }
   }
  }
  public class ReflectPoint {
   public String str1 = "ball";
   public String str2 = "basketball";
   public String str3 = "itcast";
   @Override
   public String toString()
   {
   return str1+"::"+str2+"::"+str3;
   }
  }


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值