黑马程序员_java学习日记_Java高新技术_反射(二)

 

----------------------- android培训、java培训java学习型技术博客、期待与您交流! ----------------------

成员变量反射的综合实例:(得到一个对象的Class成员变量的Field对象数组遍历其中的成员变量,可以修改它)
用到两个类:
public  class PointDemo {

 private int x=2;
 public int y=3;
 private String str1,str2,str3;
 public PointDemo(int x, int y, String str1,String str2,String str3) {
  super();
  this.x = x;
  this.y = y;
  this.str1 = str1;
  this.str2 = str2;
  this.str3 = str3;
 }
 public static void main(String[] args) {
  // TODO Auto-generated method stub

 }
   
public String toString(){
 return str1+str2+str3;
}
}
 

import java.lang.reflect.*;
public class ConstructDemo {

 public static void main(String[] args)throws Exception {
  String str1 = new String("黑马程序员训练营");
  Class cls1 = str1.getClass();
  Class cls2 = String.class;
  Class cls3 = Class.forName("java.lang.String");
  System.out.println(cls1==cls2); 
  System.out.print(cls3==cls2);
  String str3 = (String)cls3.newInstance();
  System.out.println(str3+str3.length());
  Constructor constructor1=cls1.getConstructor(String.class);
  String str4=(String)constructor1.newInstance("黑马");
  System.out.println(str4+str4.charAt(1));
  PointDemo pt1=new PointDemo(7,10,"ball","basketball","qin");
  Field fieldX=PointDemo.class.getDeclaredField("x");
  fieldX.setAccessible(true);
  
  System.out.println(fieldX.get(pt1));
  Field fieldY=pt1.getClass().getField("y");
  System.out.println(fieldY.get(pt1));
  System.out.println(pt1);
  changeVallue(pt1);
  System.out.println(pt1);
 }

 private static void changeVallue(PointDemo pt1) {
  Field[] fields = pt1.getClass().getDeclaredFields();
  
  for(Field field:fields){
   field.setAccessible(true);
   if(field.getType() == String.class){//比较的是同类字节码应该用==而不用equals();
   String oldValue;
   try {
    oldValue = (String)field.get(pt1);
    String newValue =oldValue.replace('b', 'a');
    field.set(pt1, newValue);
   } catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
   }
  }
  
 }

}

 

成员方法的反射:
Method类:代表类中的成员方法
语法:例子 Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);
调用:通常的方式是String类的实例.方法 str.charAt(1);
反射方式 charAt.invoke(str,1);如果传递给Method对象的invoke()方法的第一个参数 为NUll,这意味着该Method对象对应的是一个静态方法!

 

对接收数组参数的成员方法进行反射:

用反射方式执行某个类中的main方法,写一个程序,这个程序能根据用户提供的类名,去执行该类中的main()方法。我们知道启动Java程序的main方法的参数是一个字符串数组,即public static void main(String [] args),通过反射方式来调用这个main方法时,该如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按照jdk1.4的语法,数组中的每个元素对应一个参数,?jdk1.5肯定要兼容jdk1.4的,会按照jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{"xxx"}),Java只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题.


import java.lang.reflect.Method;
public class MainMethodDemo {

 public static void main(String[] args) throws Exception{
 MainMethodTest.main(new String[]{"aaaa"});
 Method method = Class.forName(args[0]).getMethod("main", String[].class);
 method.invoke(null,(Object)new String[]{"aaa"});//第一种解决方案强制转换为Object类型
 method.invoke(null,new Object[]{new String[]{"aaa","safas"}});//第二种解决方案把String[]再次封包为Object[]
 
 }

}
class MainMethodTest{
 public static void main(String [] args){
  for(String arg:args){
   System.out.println(arg);
  }
 }
}
 

数组与Object的关系及其类型:
具有相同维数和元素类型的数组属于同一个类型,即具有 相同的Class实例对象,代表数组的Class实例对象的getSuperclass()方法返回的父类为Object类对应的Class.基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当作Object类型也可以当作Object[]类型使用。


Arrays.asList()方法处理 int[]和String[]时的差异:
import java.util.Arrays;
public class PrintArrayDemo {

 public static void main(String[] args) {
  int [] a1 = new int[]{1,2,3};

  int [][] a2 = new int[][]{{1,2,3},{4,5}};
  String [] a3 = new String[]{"a","b","c"};
  
  
  System.out.println(a1);
  System.out.println(a2);
  System.out.println(a3);
  /*[I@192d342
    [[I@6b97fd
    [Ljava.lang.String;@1c78e57*/
  System.out.println(Arrays.asList(a1));
        System.out.println(Arrays.asList(a2));
  System.out.println(Arrays.asList(a3));
  /*[[I@192d342]
          [[I@1e63e3d, [I@1004901]
          [a, b, c]*/
 }

}
非基本类型的数组或非基本类型数组的数组,不能被直接打印出来

对数组进行反射:
Array是用于完成对数组的反射操作。我们无法用反射的方式得到整个数组的类型,我们只能得到数组元素的具体类型,我们可以遍历所有的元素,如果元素的类型都相同我们也就得到了该数组的类型,但这只是个特例,如定义一个Object[]数组里面可以放任何类型的对象

反射的价值作用:反射的主要是用来实现框架,框架使开发效率大大提高。

 

----------------------- android培训、java培训java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima

 

 

你可能感兴趣的:(黑马程序员_java学习日记_Java高新技术_反射(二))