[黑马程序员]--反射

来源:互联网 发布:java微信开发demo 编辑:程序博客网 时间:2024/06/07 00:44

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

1,概述

    要想对一个类进行解剖,就必须先获取到该类的字节码文件对象。
    其实也就是要获取到字节码文件对象的描述类Class。
 
    那么,我们有几种方式获取到一个class文件的Class对象呢?
    1:通过对象的getClass()方法获取
    2:任意类型的都有一个静态class属性
   3:通过Class类的一个forName(String className)静态方法返回一个Class对象
       className必须是全路径名称。也就是如果有包,必须带包名。
  
   一般来说,如果自己写案例,用前两种都是可以的。
   但是,开发中一般使用第三种。为什么呢?
   因为第三种方式接受的是一个字符串路径,将来可以通过配置文件获取,通用性好。

|--常见的获取反射类的方法总结

程序如下:

public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {// 方式1Person p = new Person();Class c = p.getClass();Person p2 = new Person();Class c2 = p2.getClass();System.out.println(p == p2);// falseSystem.out.println(c == c2);// true// 方式2Class c3 = Person.class;System.out.println(c == c3);// true// 方式3Class c4 = Class.forName("cn.itcast_01.Person");System.out.println(c == c4);// true}}
class Person {private String name;int age;public String address;public Person() {}Person(String name) {this.name = name;}public Person(String name, int age) {this.name = name;this.age = age;}public void show() {System.out.println("show");}public void method(String name) {System.out.println("show " + name);}public String function(String name, int age) {return name + "***" + age + "***" + "function";}private void hello() {System.out.println("hello");}@Overridepublic String toString() {return name + "***" + age;}}

2,通过反射获取构造方法

|--历程1

程序如下:

public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException,InvocationTargetException {// 获取字节码文件对象Class c = Class.forName("cn.itcast_01.Person");// 获取构造方法// public Constructor[] getConstructors() 所有公共构造方法// Constructor[] cons = c.getConstructors();// public Constructor[] getDeclaredConstructors() 所有构造方法Constructor[] cons = c.getDeclaredConstructors();for (Constructor con : cons) {System.out.println(con);}System.out.println("**************************************");// 获取单个的构造方法对象// public Constructor getConstructor(Class... parameterTypes)// 参数指的是你的构造方法的形式参数的classe类型Constructor con = c.getConstructor();// System.out.println(con);/* * Person p = new Person(); System.out.println(p);//null***0 */// 通过反射获取到的构造方法对象创建对象// public Object newInstance(Object... initargs)// 这里指的是实际传递的参数Object obj = con.newInstance();System.out.println(obj);//Person p = (Person)obj;//p.show();System.out.println("**************************************");/* * Person p = new Person("林青霞",28); * System.out.println(p); //林青霞***28 */Class[] classes = new Class[2];classes[0] = String.class;classes[1] = int.class;Constructor con2 = c.getConstructor(classes);//System.out.println(con2);//通过带参数构造器创建对象Object[] objs = new Object[2];objs[0] = "林青霞";objs[1] = 28;Object obj2 = con2.newInstance(objs);System.out.println(obj2);}}

|--历程2

程序如下:

public class ReflectDemo2 {public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException,InvocationTargetException {// 获取Class文件对象Class c = Class.forName("cn.itcast_01.Person");// 获取带两个参数的构造方法// Class[] classes = new Class[2];// classes[0] = String.class;// classes[1] = int.class;// Constructor con = c.getConstructor(classes);// Constructor con = c.getConstructor(new Class[] { String.class,// int.class });Constructor con = c.getConstructor(String.class, int.class);// Object[] objs = new Object[2];// objs[0] = "林青霞";// objs[1] = 28;// Object obj = con.newInstance(objs);// Object obj = con.newInstance(new Object[] { "林青霞", 28 });Object obj = con.newInstance("林青霞", 28);System.out.println(obj);}}

3,通过反射获取成员变量

|--历程

程序如下:

 public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException, SecurityException, NoSuchMethodException,InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException {// 获取字节码文件对象Class c = Class.forName("cn.itcast_01.Person");// 获取成员变量// public Field[] getFields() 获取公共的成员变量// Field[] fields = c.getFields();// public Field[] getDeclaredFields() 获取成员变量Field[] fields = c.getDeclaredFields();for (Field f : fields) {System.out.println(f);}System.out.println("************************************");// 单个获取// public Field getField(String name)// Field f = c.getField("address");// public Field getDeclaredField(String name)Field f = c.getDeclaredField("name");// System.out.println(f);// 获取无参数构造方法Constructor con = c.getConstructor();Object obj = con.newInstance();// public void set(Object obj,Object value)// obj其实就是对象,value就是值// public void setAccessible(boolean flag) 暴力访问f.setAccessible(true);f.set(obj, "林青霞");// 私有的成员变量和方法不能直接被使用。System.out.println(obj);}}

4,通过反射获取成员属性

|--历程

程序如下:

public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException,InvocationTargetException {// 获取字节码文件对象Class c = Class.forName("cn.itcast_01.Person");// public Method[] getMethods() 获取所有的本身及其父类的公共方法// Method[] methods = c.getMethods();// public Method[] getDeclaredMethods() 获取本类的所有方法Method[] methods = c.getDeclaredMethods();for (Method m : methods) {System.out.println(m);}System.out.println("****************************************");// 通过无参构造创建一个对象Constructor con = c.getConstructor();Object obj = con.newInstance();// 获取单个的方法// public Method getMethod(String name,Class... parameterTypes)// 第一个是方法名称,第二个是参数的class类型Method m = c.getMethod("show");/* * Person p = new Person(); p.show(); */// public Object invoke(Object obj,Object... args)// Object表示返回值类型,obj表示是哪个对象调用方法,args是实际传递的参数m.invoke(obj);System.out.println("****************************************");Method m2 = c.getMethod("method", String.class);m2.invoke(obj, "周星驰");System.out.println("****************************************");Method m3 = c.getMethod("function", String.class,int.class);Object oo = m3.invoke(obj, "周润发",55);System.out.println(oo);System.out.println("****************************************");Method m4 = c.getDeclaredMethod("hello");m4.setAccessible(true);m4.invoke(obj);}}

5,两个应用历程

|--在ArrayList<Integer>中写String

程序如下:

public class ArrayListTest {public static void main(String[] args) throws NoSuchMethodException,SecurityException, IllegalAccessException,IllegalArgumentException, InvocationTargetException {ArrayList<Integer> array = new ArrayList<Integer>();// array.add(10);// array.add("hello");Class c = array.getClass();Method m = c.getMethod("add", Object.class);m.invoke(array, "hello");m.invoke(array, "world");System.out.println(array);}}

|--配置文件

程序如下:

public class Test {public static void main(String[] args) throws Exception {// Student s = new Student();// s.study();// Teacher t = new Teacher();// t.study();// 用反射实现/* * 配置文件的键应该是已知的 className methodName */Properties prop = new Properties();FileReader fr = new FileReader("person.txt");prop.load(fr);fr.close();String className = prop.getProperty("className");String mehodName = prop.getProperty("methodName");// 获取字节码文件对象Class c = Class.forName(className);// 创建对象Constructor con = c.getConstructor();Object obj = con.newInstance();// 获取方法Method m = c.getMethod(mehodName);m.invoke(obj);}}

class Teacher {public void study() {System.out.println("老师也得学习");}}

class Student {public void study() {System.out.println("学生爱学习");}}





原创粉丝点击