------- android培训、java培训、期待与您交流! ----------
当我们写好一个程序时,Java 语言把每个单独的类 Class 和接口 Implements 编译成单独的一个 . class 文件,这些文件对于 Java 运行环境来说就是一个个可以动态加载的单元。此外这些class文件就是这些类或接口的字节码文件,为了操作这些字节码文件,java把这些字节码文件归为Class类。
那么怎样来理解Class类呢?
类就是一些具有相同特性的对象的抽象形式,比如Person类,就把人的姓名,年龄,身高等共有的数据给抽象出来。
而Class类就是所有类字节码文件对象的抽象形式,所有的类都是具有字段,构造方法,成员方法这些相同的元素,
Class类就把这些类共有的特性分为了Field,Constructor,Method类。
而反射就是建立在Class类的基础上来动态的获取类中的信息,调用这些类的方法和属性,要想操作这些类必须先获得这些类的字节码文件对象。比如Person类就具有自己特有的字节码文件,他的对象P1和P2所对应的类的字节码文件都是一样的。
下面通过一个例子就把关于反射的大部分操作方法给展现出来。
- //定义一个Person类,分别有公有和私有的构造方法、字段和方法,然后用反射来操作这个类
- public class Person {
- private String namePrivate;
- public static int ageStatic;
- public String namePublic;
- public int agePublic;
- Person() {
- }
- public Person(String namePublic,int agePublic)
- {
- this.namePublic = namePublic;
- this.agePublic = agePublic;
- System.out.println("我是公有构造方法"+"公有字段"+namePublic+agePublic);
- }
- public Person(int agePublic)
- {
- this.agePublic = agePublic;
- }
- private Person(String namePrivate)
- {
- this.namePrivate = namePrivate;
- System.out.println("我是私有有构造方法"+"私有字段"+namePrivate);
- }
- public Person getPersonPublic(String namePublic ,int agePublic )
- {
- this.agePublic = agePublic;
- this.namePublic = namePublic;
- Person p = new Person();
- return p;
- }
- public int getAgePublic()//空参数的构造方法
- {
- return agePublic;
- }
- private String getNamePrivate(String name)
- {
- return namePrivate;
- }
- public static int getAgeStatic(int age)
- {
- Person.ageStatic = age;
- return ageStatic;
- }
- }
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import javax.activation.FileDataSource;
- import cn.cn.cn.Student;
- public class ClassDemo {
- public static void main(String[] args) throws Exception
- {
- new Student();
- /*
- * 有三种方式可以得到Person类的Class
- * 方式一:知道Person的一个对象p
- * Class c1 = p.getClass();
- * 方式二:知道有个类叫Person
- * Class c2 = Person.class;
- * 方式三:知道有个类叫Person 此种方式的字符串参数要包括包名,一般是通过配置文件获得的
- * Class c3 = Class.forName("Person");
- */
- //方式一:必须要先有个对象
- Person p = new Person();
- Class c1 = p.getClass();
- //方式二
- Class c2 = Person.class;
- // 方式三
- Class c3 = Class.forName("Person");//Person保存在默认包中
- //如果我们定义一个Student类他的包名为 cn.cn.cn,用之前先导入包,最上面:import cn.cn.cn.Student;
- Class c4 = Class.forName("cn.cn.cn.Student");
- System.out.println(c4);
- /*
- 1 * 构造方法的获得方式
- *
- * 1.获得公有的构造方法
- * 1.1获得所有的公有方法
- * 1.2获得指定的公有方法
- * 2.获得所有的构造方法
- * 2.1获得所有的方法
- * 2.2获得指定的私有方法
- */
- //1.1获得所有公有的构造方法,调用Class对象的getConstructors方法,他会返回返回一个包含某些 Constructor 对象的数组
- Constructor[] cons = c1.getConstructors();
- for(Constructor s : cons)
- {
- System.out.println(s); //打印结果public Person(int) public Person(java.lang.String,int)
- }
- // 1.2 获得指定的公有方法,调用Class方法的getConstructor方法,返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
- //指定的方法就是将构造方法的参数值传入
- Constructor con = c1.getConstructor(String.class,int.class);
- System.out.println(con); // public Person(java.lang.String,int)
- // 2.获得所有的私有方法以及指定的私有方法,与上面的方法类似,就多了个Declared关键字
- Constructor[] conprs = c1.getDeclaredConstructors();
- Constructor conpr = c1.getDeclaredConstructor(String.class);
- /***************************************************************************************/
- /*
- 2 * 获得字段的方法
- 2.1获得所有的公有字段
- 2.2获得所有的字段
- 2.3获得指定的私有字段
- */
- //获得所有的公有字段
- Field[] filed = c1.getFields();
- //获得所有的 私有有字段
- Field[] fieldpr = c1.getDeclaredFields();
- //获得指定的私有字段namePrivate
- Field f = c1.getDeclaredField("namePrivate");
- System.out.println(f);
- /***************************************************************************************/
- /*
- 3 * 获得字段的方法
- 3.1获得所有的公有方法
- 3.2获得所有的方法
- 3.3获得指定的公有方法
- 3.4获得静态方法
- */
- //3.1获得所有的公有方法
- Method [] ms = c1.getMethods();
- //3.1获得所有的方法
- Method [] mps = c1.getDeclaredMethods();
- //3.3获得指定的公有方法,调用getDeclaredMethod(String name ,Class<?>... parameterTypes)
- // 他又两个参数,name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组,
- //它按声明顺序标识该方法的形参类型。
- Method m = c1.getDeclaredMethod("getNamePrivate", String.class);
- //如果想获取空参数的构造方法,将参数表写为null就行了
- Method mnull = c1.getMethod("getAgePublic", null);
- //3.4获得静态方法,和普通的获得方法没什么不同
- Method mm = c1.getMethod("getAgeStatic", int.class);
- /***************************************************************************************/
- /*
- 4 如何利用反射实例化一个对象,并使用它的方法
- 4.1利用方式实例化一个对象
- 4.1.1利用默认的无参构造函数实例化一个对象
- 4.1.2利用指定的公共的构造函数实例化一个对象
- 4.1.3利用指定的私有的构造函数实例化一个对象
- 4.2利用反射使用方法
- 4.2.1使用公共的方法
- 4.2.2使用私有的方法
- 4.2.3使用静态方法
- * */
- // 4.1.1利用默认的无参构造函数实例化一个对象
- Person p1 = (Person)c1.newInstance();
- // 4.1.2利用指定的公共的构造函数实例化一个对象
- Constructor con1 = c1.getConstructor(String.class,int.class);
- Person p2 = (Person)con1.newInstance("liming",20);
- System.out.println(p2.agePublic+p2.namePublic);
- //利用指定的私有的构造函数实例化一个对象
- Constructor con3 = c1.getDeclaredConstructor(String.class);
- //私有的必需要设置访问权限,否则不能访问,对于字段和方法也是一样的
- con3.setAccessible(true);
- con3.newInstance("wang");
- // 4.2.1使用公共的方法
- Method m1 = c1.getMethod("getAgePublic", null);
- Object obj = c1.newInstance();
- int age = (Integer) m1.invoke(obj, null);
- //4.2.2使用私有的方法,与上面类似,只要设置权限就可以了
- //4.2.3使用静态方法。和上面类似,只要invoke的第一个参数设为null
- Method m2 = c1.getMethod("getAgeStatic", int.class);
- int age1 = (Integer) m2.invoke(null, 24);
- System.out.println(age1);
- }
- }