Class反射

1 概念

通过类的字节码文件对象 动态创建对象或者获取类的成员
字节码文件对象:类的字节码文件被封装为对象:Class
创建类:抽取数据做变量  抽取功能做方法
动态:主动获取: 杀鸡取卵 
静态:被动获取: 吃的鸡蛋是被动获取:鸡下蛋 才能吃
  • 涉及的类
Class: 描述字节码文件
Constructor:构造方法  :: 描述类的构造方法
Method:普通方法:::描述普通方法
Field:成员变量:::描述成员变量

2 Class:类的字节码文件

  • 获取Class对象的方法
//获取字节码文件对象方式
//方式1:类的静态成员class
Class c1=Demo01.class;
System.out.println(c1);//class com.zhiyou100.demo04.reflect.Demo01
//方式2:Object类的getClass()
Class c2=new Demo01().getClass();
System.out.println(c1==c2);//true
//方式3:Class类的静态方法:forName(类名全称)
Class c3=Class.forName("com.zhiyou100.demo04.reflect.Demo01");
System.out.println(c3==c2);//true

//框架:为实现某个功能或者场景 创建的半成品---毛坯房
//把房子必须的门 窗 墙 隔断  水电 提供出来---毛坯房
//框架:把相同场景、功能的代码抽取出来  使用时填充自己的数据和个性化的内容  就形成了完整的项目
  • 常用方法
 * Class类方法
     * 1  static Class<?> forName(String className) 
     *           根据类的全称获取类的字节码文件对象
     * 2   String getName()  获取类的全称:包名.类名
     *     String getSimpleName()  获取类名
     * 3   Constructor[] getConstructors()  :获取所有public修饰符的构造方法
     *     Constructor[] getDeclaredConstructors() :获取所有任意修饰符的构造方法
     *     Constructor getConstructor(Class<?>... parameterTypes):获取指定参数的public构造方法
     *     Constructor getDeclaredConstructor(Class<?>... parameterTypes):获取指定参数的任意修饰符的构造方法             
     * 4   Method getMethod(String name, Class<?>... parameterTypes):获取一个public修饰符的普通方法:指定方法名+参数列表类型
     *     Method getDeclaredMethod(String name, Class<?>... parameterTypes):获取一个任意修饰符的普通方法:指定方法名+参数列表类型  
	 *	   Method[] getMethods() :获取所有本类和所有父类种定义的public修饰符的普通方法
	 *	   Method[] getDeclaredMethods() :获取本类中定义的任意修饰符的普通方法                  
     * 5  Field[] getFields():获取所有public修饰符的成员变量
     *    Field getField(String name):获取一个指定名字的public修饰符的成员变量
     *    Field[] getDeclaredFields():获取所有任意修饰符的成员变量
     *    Field getDeclaredField(String name) :获取一个指定名字的任意修饰符的成员变量
     * 6  Class<?>[] getInterfaces():获取当前类实现的所有接口
     *    Class<? super T> getSuperclass()  :获取当前类的直接父类 
     * 7  T newInstance() :创建对象  
  • 代码
public class Demo01Class {
	public static void main(String[] args) throws Exception {
        //获取名字
        System.out.println("getName="+c1.getName());//com.zhiyou100.demo04.reflect.Demo01
		System.out.println("getSimpleName="+c1.getSimpleName());//Demo01
		
		//构造方法
		Constructor[] arr1=c1.getConstructors();
		System.out.println(Arrays.toString(arr1));//[public com.zhiyou100.demo04.reflect.Demo01()]
		Constructor[] arr2=c1.getDeclaredConstructors();//[protected com.zhiyou100.demo04.reflect.Demo01(java.lang.String,int), public com.zhiyou100.demo04.reflect.Demo01(), com.zhiyou100.demo04.reflect.Demo01(int)]
		System.out.println(Arrays.toString(arr2));
		
		System.out.println(c1.getConstructor());
		//System.out.println(c1.getConstructor(String.class,int.class));//NoSuchMethodException
		System.out.println(c1.getDeclaredConstructor(String.class,int.class));
		
		
		//普通方法
		System.out.println("---------");
		Method[] arr3=c1.getDeclaredMethods();
		System.out.println(Arrays.toString(arr3));
		Method[] arr4=c1.getMethods();
		System.out.println(Arrays.toString(arr4));
		System.out.println(c1.getDeclaredMethod("haha", int.class,String.class));
		System.out.println(c1.getMethod("equals", Object.class));
		
		//成员变量
		System.out.println(Arrays.toString(c1.getDeclaredFields()));
		System.out.println(Arrays.toString(c1.getFields()));
		System.out.println(c1.getDeclaredField("a"));
		
		
		//获取所有的接口
		System.out.println(Arrays.toString(c1.getInterfaces()));
		System.out.println(c1.getSuperclass());
		
		Demo01 d1=(Demo01)c1.newInstance();
		System.out.println(d1.b);    
	}

}
class Demo01 implements I1,I2,I3{
	private int a;
	protected long b=100;
	public int c=2;
	public static int i=1;
	public Demo01(){}
	Demo01(int a){}
	protected Demo01(String s,int a){}
	
	public void hehe(){
		System.out.println("public void hehe()");
	}
	 void haha(int a){
		System.out.println("public void haha(int a)");
	}
	private void haha(int a,String b){
		System.out.println("public void haha(int a,String b)");
	}
}
interface  I1{}
interface I2{}
interface I3{}

3 Constructor 构造方法

  • 常用方法
    * Constructor的方法
    * 1  String getName()  
    * 2  int getModifiers()  
    * 3  Class<?>[] getParameterTypes() 
    * 4  T newInstance(Object... initargs) :创建当前类的对象  
  • 代码
public static void main(String[] args) throws Exception{
    Class c1=Class.forName("com.zhiyou100.demo04.reflect.Demo02");
    Constructor con1=c1.getDeclaredConstructor(int.class);
    System.out.println(con1);

    Constructor[] arr=c1.getDeclaredConstructors();
    for (Constructor con : arr) {
        System.out.println(con);
        System.out.println("方法名字:"+con.getName());
        System.out.println("方法修饰符:"+con.getModifiers());
        System.out.println("参数列表:"+Arrays.toString(con.getParameterTypes()));
        System.out.println();
    }

    Demo02 d1=(Demo02)con1.newInstance(1);
    System.out.println(d1.a);//1
}
class Demo02{
    int a;
    public Demo02(){}
    Demo02(int a){
        this.a=a;
    }
    protected Demo02(String s,int a){}
    private Demo02(String s,long a){}
    Demo02(String s,int a,float b){}

    public void hehe(){
        System.out.println("public void hehe()");
    }
}

4 Field 字段

  • 常用方法
     * Field类的方法
     * 1 String getName()  :获取字段名
     * 2 Class<?> getType() :获取字段类型
     * 3 Object get(Object obj)  :获取参数对象的当前属性的值
     * 4 void set(Object obj, Object value) :设置参数对象obj的当前属性的值  为value
     * 5  int getModifiers() :获取字段的修饰符
     * 6  void setAccessible(boolean )是否取消范围修饰符的检查:暴力访问
  • 代码
public static void main(String[] args)throws Exception {
    Class c1=Class.forName("com.zhiyou100.demo04.reflect.Demo03");
    Field[]  arr=c1.getDeclaredFields();
    for (Field field : arr) {
        System.out.println("属性名="+field.getName());
        System.out.println("属性类型="+field.getType());
        System.out.println("属性修饰符="+field.getModifiers());
        System.out.println("------");
    }
    //创建Demo03对象
    Demo03  d3=(Demo03)c1.newInstance();
    System.out.println(d3);//必须有无参数的构造方法:

    Field fa=c1.getDeclaredField("a");
    fa.set(d3, 3);
    Field fb=c1.getDeclaredField("b");
    fb.set(d3, 4);
    Field fc=c1.getDeclaredField("c");
    fc.set(d3, 5);

    Field ff=c1.getDeclaredField("f");//IllegalAccessException
    //暴力访问:取消编译器对范围修饰符的检查
    ff.setAccessible(true);
    ff.set(d3, 6);

    System.out.println(d3+"::::"+d3.c);

    //d3.a=5;
}
class Demo03{
    int a;
    public int b;
    protected static float c=11;
    public long d=12;
    private int f=1;
    Demo03(int  e){}
    public Demo03(){}
    @Override
    public String toString() {
        return "Demo03 [a=" + a + ", b=" + b + ", d=" + d + ",f="+f+"]";
    }
}

5 Method 普通方法

  • 常用方法
     * Method的方法
     * 1 int getModifiers() 
     * 2 String getName() 
     * 3 Class<?> getReturnType()  
     * 4 Class<?>[] getParameterTypes()  
     * 5 Class<?>[] getExceptionTypes()  
     * 6 Object invoke(Object obj, Object... args) 
     * 7 void setAccessible(boolean )是否取消范围修饰符的检查:暴力访问 
  • 代码
public static void main(String[] args) throws Exception{
    Class c1=Class.forName("com.zhiyou100.demo04.reflect.Demo04");
    Method[] arr=c1.getDeclaredMethods();
    for (Method method : arr) {
        System.out.println("方法名:"+method.getName());
        System.out.println("方法返回值类型:"+method.getReturnType());
        System.out.println("方法参数列表:"+Arrays.toString(method.getParameterTypes()));
        System.out.println("方法修饰符:"+method.getModifiers());
        System.out.println("方法异常:"+Arrays.toString(method.getExceptionTypes()));
        System.out.println("--------"+method);
    }
    //创建对象
    Demo04 d4=(Demo04)c1.newInstance();
    //调用方法1:
    Method m2=c1.getDeclaredMethod("get1", int.class,float.class);
    System.out.println(m2);
    Object result=m2.invoke(d4, 3,4f);
    System.out.println("result="+result);

    //调用方法2:
    Method m3=c1.getDeclaredMethod("get2"); 
    //暴力访问
    m3.setAccessible(true);
    m3.invoke(d4, null);//IllegalAccessException
}

class Demo04{
    public int get1()throws Exception{
        System.out.println("普通方法:public int get1()");
        return 1;
    }
    public int get1(int a,float b)throws IOException,ParseException{
        System.out.println("普通方法:public int get1(int a="+a+",float b="+b+")");
        return a+1;
    }
    private  void get2(){
        System.out.println("private  void get2()");
    }
}
posted @ 2021-10-30 22:18  RenVei  阅读(58)  评论(0编辑  收藏  举报