java反射
反射的概念:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
下面用实例来讲解
package fanshe;
public class Learn {
Learn(String str){
System.out.println("默认str构造函数 ");
}
public Learn() {
System.out.println("公有无参构造函数");
}
public Learn(String name,int age) {
System.out.println("共有name age构造函数");
}
protected Learn(boolean n) {
System.out.println("受保护的构造方法 n = ");
}
private Learn(int age) {
System.out.println("私有构造方法age");
}
}
获取Class对象的三种方式
Object ——> getClass();
任何数据类型(包括基本数据类型)都有一个“静态”的class属性
通过Class类的静态方法:forName(String className)(常用)
package fanshe;
public class Fanshe {
public static void main(String args[]) {
Learn stu1 = new Learn();
Class stuclass = stu1.getClass();
Class stuclass2 = Learn.class;
try {
Class stuclass3 = Class.forName("fanshe.Learn");
}catch(Exception e) {
e.printStackTrace();
}
}
}
后面我将用第三种方法
接下来我将通过代码展示
案例类
package fanshe;
public class Learn {
public String a;
public int b;
private int c;
protected boolean d;
Learn(String str){
System.out.println("默认构造函数 "+str);
}
public Learn() {
System.out.println("公有无参构造函数");
}
public Learn(String name,int age) {
System.out.println("共有构造函数"+name+" "+age);
}
protected Learn(boolean n) {
System.out.println("受保护的构造方法"+n);
}
private Learn(int age) {
System.out.println("私有构造方法"+age);
}
public void getA(int a) {
System.out.println("公有普通方法"+a);
}
protected void getB(int a) {
System.out.println("保护普通方法"+a);
}
private void getC(int a) {
System.out.println("私有普通方法"+a);
}
public class Study{
}
private class Study2{
}
}
测试类
下面用实例来讲解
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Fanshe {
public static void main(String args[]) {
try {
Class stuclass = Class.forName("fanshe.Learn");
System.out.println(stuclass.getPackage());//包名
System.out.println(stuclass.getName());//类名
System.out.println(stuclass.getSuperclass());//父类名
System.out.println(stuclass.getInterfaces());//接口名
//获取构造方法
Constructor[] m = stuclass.getConstructors();
for(Constructor i:m){
System.out.println(i);
}//所有public构造方法
System.out.println();
m = stuclass.getDeclaredConstructors();
for(Constructor i:m){
System.out.println(i);
}//所有构造方法
System.out.println();
Constructor n = stuclass.getConstructor(String.class,int.class);;
System.out.println(n);//指定参数的public构造方法
System.out.println();
n = stuclass.getDeclaredConstructor(int.class);
System.out.println(n);//指定参数构造方法
System.out.println();
System.out.println(n.isVarArgs());//看方法是否可以带可变参数
System.out.println(n.getParameterTypes());//获取参数类型
System.out.println(n.getExceptionTypes());//获取可能抛出的异常
n.setAccessible(true);//无视权限
System.out.println(n.newInstance(123));
System.out.println(stuclass.getConstructor().newInstance());//创建实例对象
System.out.println();
//获取普通话方法
Method[] m1 = stuclass.getMethods();
for(Method i:m1) {
System.out.println(i);
}//获取所有public方法
System.out.println();
Method n1 = stuclass.getMethod("getA", int.class);
System.out.println(n1);//获取指定参数的public方法
System.out.println();
m1 = stuclass.getDeclaredMethods();
for(Method i:m1) {
System.out.println(i);
}//获取所有方法
System.out.println();
n1 = stuclass.getDeclaredMethod("getA", int.class);
System.out.println(n1);//获取指定参数方法
System.out.println();
System.out.println(n1.getName());//获取方法名
System.out.println(n1.getParameterTypes());//获取方法参数类型
System.out.println(n1.getReturnType());//获取方法返回值类型
Learn stu = (Learn)stuclass.getConstructor().newInstance();
n1.invoke(stu, 123);//通过实例对象调用方法
System.out.println();
//获取成员变量
Field[] m2 = stuclass.getFields();
for(Field i:m2) {
System.out.println(i);
}//获取所有public字段
System.out.println();
Field n2 = stuclass.getField("a");
System.out.println(n2);//获取指定参数的public对象
System.out.println();
m2 = stuclass.getDeclaredFields();
for(Field i:m2) {
System.out.println(i);
}//获取所有字段
System.out.println();
n2 = stuclass.getDeclaredField("b");
stu = (Learn)stuclass.getConstructor().newInstance();
System.out.println(n2);//获取指定字段
System.out.println();
System.out.println(n2.getName());//获取字段名
System.out.println(n2.getType());//获取字段类型
n2.set(stu, 123);//设置字段值,先实例化一个对象
System.out.println(n2.get(stu));//通过对象获取指定字段值
System.out.println(n2.getInt(stu));
//n2.getFloat()
//n2.getboolean()
//n2.setAccessible()
System.out.println();
//获取内部类
Class[] m3 = stuclass.getClasses();
for(Class i:m3) {
System.out.println(i);
}//获取所有public内部类
System.out.println();
m3 = stuclass.getDeclaredClasses();
for(Class i:m3) {
System.out.println(i);
}获取所有内部类
System.out.println();
Class n3 = stuclass.getDeclaringClass();
System.out.println(n3);//判断该类是否为内部类,是返回它的成员类
}catch(Exception e) {
e.printStackTrace();
}
}
}