A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© Kevin.Kang 高级黑马   /  2015-8-11 15:55  /  375 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

简单来说反射就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。使用反射首先必须得到class文件对象,其实也就是得到Class类的对象。
  1. package com.kxg_01;

  2. /*
  3. * 获取class文件对象的方式:
  4. *
  5. *        1.Object类的getClass()方法,返回是一个Class类。
  6. *        2.数据类型的静态属性class
  7. *        3.Class类中的静态方法:public static Class forName(String className)
  8. */
  9. public class ClassDemo {
  10.         public static void main(String[] args) throws ClassNotFoundException {
  11.                 // 方式1
  12.                 Person p = new Person();
  13.                 Class c = p.getClass();

  14.                 // 方式2
  15.                 Class c2 = Person.class;

  16.                 // 方式3
  17.                 Class c3 = Class.forName("com.kxg_01.Person");
  18.         }
  19. }

  20. class Person {

  21. }
复制代码



8 个回复

倒序浏览
本帖最后由 Kevin.Kang 于 2015-8-11 17:37 编辑

通过反射获取构造方法:
定义一个类:
  1. package com.kxg_01;

  2. public class Person {
  3.         private String name;
  4.         int age;
  5.         public String adress;

  6.         public Person() {
  7.         }

  8.         Person(String adress, int age) {
  9.                 this.adress = adress;
  10.                 this.age = age;
  11.         }

  12.         private Person(int age) {
  13.                 this.age = age;
  14.         }

  15.         public Person(String name, int age, String adress) {
  16.                 this.name = name;
  17.                 this.adress = adress;
  18.                 this.age = age;
  19.         }

  20.         public void show() {
  21.                 System.out.println("show");
  22.         }

  23.         public void show2(String s) {
  24.                 System.out.println("show2"+s);
  25.         }

  26.         public String show3(String s) {
  27.                 return "show3:" + s;
  28.         }

  29.         private void show4(String s) {
  30.                 System.out.println("show4");
  31.         }

  32.         @Override
  33.         public String toString() {
  34.                 return "Person [name=" + name + ", age=" + age + ", adress=" + adress
  35.                                 + "]";
  36.         }
  37. }
复制代码




利用反射获取:
  1. package com.kxg_01;
  2. import java.lang.reflect.Constructor;

  3. public class ClassDemo2 {
  4.         public static void main(String[] args) throws Exception{
  5. //                获取字节码文件
  6.                 Class c = Class.forName("com.kxg_01.Person");
  7.                
  8.                 // public Constructor[] getConstructors()
  9.                 // 返回一个包含某些 Constructor 对象的数组,
  10.                 // 这些对象反映此 Class 对象所表示的类的所有公共构造方法。也就是public修饰的构造方法
  11.                 Constructor[] cons = c.getConstructors();
  12.                 for (Constructor con : cons) {
  13.                         System.out.println(con);
  14.                 }
  15.                 System.out.println("------------------------------------");

  16.                 // public Constructor[] getDeclaredConstructors()
  17.                 // 返回 Constructor 对象的一个数组, 这些对象反映此 Class 对象表示的类声明的所有构造方法。
  18.                 // 它们是公共、保护、默认(包)访问和私有构造方法。
  19.                 Constructor[] cons2 = c.getDeclaredConstructors();
  20.                 for (Constructor con : cons2) {
  21.                         System.out.println(con);
  22.                 }

  23.                 // public Constructor getConstructor(Class<?>... parameterTypes)
  24.                 // 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
  25.                 // 参数表示的是你要获取的构造方法的构造参数个数以及数据类型的class字节码文件对象
  26.                 Constructor con = c.getConstructor(String.class, int.class);
  27.         }
  28. }
复制代码




回复 使用道具 举报
本帖最后由 Kevin.Kang 于 2015-8-11 16:37 编辑

通过得到的构造方法创建对象
  1. package com.kxg_01;

  2. import java.lang.reflect.Constructor;

  3. public class ClassDemo3 {
  4.         public static void main(String[] args) throws Exception{
  5. //                使用Constructor类中的public T newInstance(Object... initargs)方法创建一个对象
  6.                 Class c   = Class.forName("com.kxg_01.Person");
  7.                
  8.                 // 获取无参构造,创建对象
  9.                 Constructor con = c.getConstructor();
  10.                 Object obj = con.newInstance(null);
  11.                 System.out.println(obj);
  12.                
  13.                 // 获取有参构造,创建对象
  14.                 Constructor con2 = c.getConstructor(String.class, int.class,
  15.                                 String.class);
  16.                 Object obj2 = con2.newInstance("周星驰", 30, "中国");
  17.                 System.out.println(obj2);
  18.         }
  19. }
复制代码




回复 使用道具 举报
获取私有构造方法并创建对象:
  1. package com.kxg_01;

  2. import java.lang.reflect.Constructor;

  3. public class ClassDemo4 {
  4.         public static void main(String[] args) throws Exception {
  5.                 // public Constructor getDeclaredConstructor(Class<?>...
  6.                 // parameterTypes)
  7.                 // Class类中的此方法可以获取任意修饰符修饰的构造方法

  8.                 Class c = Class.forName("com.kxg_01.Person");

  9.                 Constructor con = c.getDeclaredConstructor(int.class);

  10.                 // 用私有方法创建对象,需要取消 Java 语言访问检查
  11.                 // Constructor类的父类中public void setAccessible(boolean flag)
  12.                 // 实现这个效果
  13.                 con.setAccessible(true);
  14.                 Object obj = con.newInstance(30);
  15.                 System.out.println(obj);

  16.         }
  17. }
复制代码



回复 使用道具 举报
获取成员变量并进行赋值
  1. package com.kxg_02;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;


  4. public class ReflectDemo {
  5.         public static void main(String[] args) throws Exception {
  6.                 // 获取字节码文件对象
  7.                 Class c = Class.forName("com.kxg_01.Person");

  8.                 // public Field[] getDeclaredFields():获取全部成员变量对象数组
  9.                 Field[] fields = c.getDeclaredFields();
  10.                 for (Field f : fields) {
  11.                         System.out.println(f);
  12.                 }
  13.                 System.out.println("-----------------------------");

  14.                 // public Field getFields():获取成员变量对象数组,只能获取公共的
  15.                 Field[] field = c.getFields();
  16.                 for (Field f : field) {
  17.                         System.out.println(f);
  18.                 }

  19.                 // public Field getField(String name):获取单个指定成员变量
  20.                 Field adressField = c.getField("adress");

  21.                 // 对成员变量进行赋值
  22.                 // 使用Field类中的public void set(Object obj,Object value)方法
  23.                 // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值
  24.                 // 想要为一个成员变量进行赋值,首先需要有一个对象
  25.                 Constructor con = c.getConstructor();
  26.                 Object obj = con.newInstance();

  27.                 adressField.set(obj, "中国");// 给obj对象的adressField字段赋值为中国
  28.                 System.out.println(obj);
  29.         }
  30. }
复制代码



回复 使用道具 举报
赞一个!!!!
回复 使用道具 举报
本帖最后由 Kevin.Kang 于 2015-8-11 17:42 编辑

获取无参无返回值方法,并调用
  1. package com.kxg_02;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Method;

  4. public class MethodDemo {
  5.         public static void main(String[] args) throws Exception {
  6.                 Class c = Class.forName("com.kxg_01.Person");

  7.                 // public Method[] getMethods():获取除了私有修饰的所有方法,包括从父类继承过来的
  8.                 Method[] methods = c.getMethods();
  9.                 for (Method m : methods) {
  10.                         System.out.println(m);
  11.                 }
  12.                 System.out.println("-----------------------");

  13.                 // public Method getMethod(String name,Class<?>... parameterTypes)
  14.                 // 第一个参数是方法名,第二个参数是该方法参数的class类型,没有就不写,或者写null
  15.                 Method m = c.getMethod("show", null);

  16.                 // public Object invoke(Object obj,Object... args)
  17.                 // 第一个参数是要调用方法的对象,第二个参数是该方法的实际参数,没有就不写,或者写null
  18.                 // 创建对象
  19.                 Constructor con = c.getConstructor();
  20.                 Object obj = con.newInstance();

  21.                 // 调用方法
  22.                 m.invoke(obj, null);
  23.         }
  24. }
复制代码

有参无返和有参有返案例
  1. package com.kxg_02;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Method;

  4. public class MethodDemo2 {
  5.         public static void main(String[] args) throws Exception {
  6.                 // 获取字节码文件对象
  7.                 Class c = Class.forName("com.kxg_01.Person");

  8.                 // 创建无参对象
  9.                 Constructor con = c.getConstructor();
  10.                 Object obj = con.newInstance();

  11.                 // 获取有参无返回值方法
  12.                 Method m = c.getMethod("show2", String.class);

  13.                 // 获取有参有返回值方法
  14.                 Method m2 = c.getMethod("show3", String.class);

  15.                 // 调用方法
  16.                 m.invoke(obj, "中国");

  17.                 String s = (String) m2.invoke(obj, "河南");
  18.                 System.out.println(s);
  19.         }
  20. }
复制代码



回复 使用道具 举报
风华正茂 来自手机 中级黑马 2015-8-11 17:41:29
8#
谢谢楼主分享,楼主辛苦了
回复 使用道具 举报
gaoduan  aaa
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马