黑马程序员技术交流社区

标题: 反射机制 [打印本页]

作者: 晚上没饭吃    时间: 2015-8-5 21:07
标题: 反射机制
java中有一个类很特殊,就是Class类,很多朋友在写程序的时候有用过比如Apple.class来查看类型信息,大家就可以把它理解为封装了类的信息,很多解释说Class类没有构造器,其实是有的,只不过它的构造方法是private的(这样是为了禁止开发者去自己创建Class类的实例)

获取实例对象
在没有对象实例的时候,主要有两种办法。
 在没有对象实例的时候,主要有两种办法。


        //获得类类型的两种方式
        Class cls1 = Role.class;
        Class cls2 = Class.forName("yui.Role");//forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。

     Object o = cls1.newInstance(); //创建一个实例
      Object 0=cls2.  getConstructors()

                  
        //Object o1 = new Role();   //与上面的方法等价

Class有4个方法来获得Constructor对象
   
public Constructor<?>[] getConstructors()                               返回类中所有的public构造器集合,默认构造器的下标为0

public Constructor<T> getConstructor(Class<?>... parameterTypes)        返回指定public构造器,参数为构造器参数类型集合
public Constructor<?>[] getDeclaredConstructors()                       返回类中所有的构造器,包括私有
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)返回任意指定的构造器
 获取类的成员变量:
                    import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class RfkecDemo4 {
     public static void main(String[] args) throws Exception {
            Class c=Class.forName ("resource.Penson" );
            Constructor con=c.getConstructor() ;
            //获取对象
           Object obj=con.newInstance();
            //读取私有成员变量
           Field addressField=c.getDeclaredField( "age");
           addressField.setAccessible( true);
            //添加年龄属性
           addressField.set(obj, 22);
           Field  nameressField=c.getDeclaredField( "name");
           nameressField.setAccessible( true);
            //添加名字属性
           nameressField.set(obj, "林青霞");
           System. out.println(obj);
     }
}

获取类的方法
     public Method[] getMethods()                                                                                         获取所有的共有方法的集合包括自己的
     public Method getMethod(String name,Class<?>... parameterTypes)                               获取指定公有方法 参数1:方法名 参数2:参数类型集合
     public Method[] getDeclaredMethods()                                                                            指定类的获取所有的方法调用私有方法
     public Method getDeclaredMethod(String name,Class<?>... parameterTypes)                  获取任意指定方法

     
import java.lang.reflect.Method;
public class RefkecDemo5 {
     public static void main(String[] args) throws Exception {
            //获取字节码
            Class  c=Class.forName("resource.Penson" );
            //获取实例对象
           Object obj= (c.getConstructor()).newInstance();
            //获取对象的方法
            //public Method getMethod(String name,Class<?>......parameterTypes)
            //第一个参数表示的方法名,第二个参数表示的方法的参数的class类型
           Method m1= c.getMethod("show", String.class);
            //public Object invoke(Object obj,Object...args)
            //返回值的Object接收,第一个参数表示对象时谁,第二参数表示调用该方法的实际参数
           m1.invoke(obj, "哈哈");
     }
}



获取类的构造方法
         import java.lang.reflect.Constructor;

public class RefkecDenmo2 {
     public static void main(String[] args) {
            // TODO Auto-generated method stub
            try {
                 //获取字节码对象
                 Class  c=Class.forName("resource.Penson" );
                 //获取带参的构造方法
                 Constructor  cons=c.getDeclaredConstructor(String.class, int.class);
                 //获取累的实例
                Object son=cons.newInstance( "林青霞",25);
                 //输出这个对象
                System. out.println(son);
           } catch (Exception e) {
                 // TODO Auto-generated catch block
                e.printStackTrace();
           }
     }

}
开发实例:用反射机制我们可以完成 很多扩展性,
如知道 a.txt文件里面的数据是
className=resource.Penson
methodName=show

用这些数据来用反射机制来做
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;

public class RefkecDemo6 {
     public static void main(String[] args) throws Exception {
     //加载键值对数据
      Properties prop= new Properties();
      FileReader fr=new FileReader( "a.txt");
      prop.load(fr);
      fr.close();
      //获取数据
      String className=prop.getProperty( "className");
      String methodName =prop.getProperty( "methodName");
      //反射
      Class c=Class.forName(className);
      Constructor con=c.getConstructor();
      Object obj=con.newInstance();
     
      //调用方法
      Method m=c.getMethod(methodName);
      m.invoke(obj);
     }
}




作者: 晚上没饭吃    时间: 2015-8-5 21:10
在楼梯口遇到邻居… “内个,帅哥,能不能借你的肩膀用下?”… 他愣了一下,然后激动的把肩膀靠过来说:“好!好!”… “谢谢你哦,麻烦你帮我把这桶水扛到七楼,电梯坏了!”… “我也借你的芳草萋萋地一用?”… 卧槽!…




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2