java之反射

前言Class类

Class类常用方法总结

  1getName():返回String形式的该类的名称。
  2 newInstance():根据某个Class对象产生其对应类的实例,它调用的是此类的默认构造方法(没有默认无参构造器会报错)
  3 getClassLoader():返回该Class对象对应的类的类加载器。
  4 getSuperClass():返回某子类所对应的直接父类所对应的Class对象
  5 isArray():判定此Class对象所对应的是否是一个数组对象
  6 getComponentType() :如果当前类表示一个数组,则返回表示该数组组件的 Class 对象,否则返回 null。
  7 getConstructor(Class[]) :返回当前 Class 对象表示的类的指定的公有构造子对象。
  8 getConstructors() :返回当前 Class 对象表示的类的所有公有构造子对象数组。
  9 getDeclaredConstructor(Class[]) :返回当前 Class 对象表示的类的指定已说明的一个构造子对象。
  10 getDeclaredConstructors() :返回当前 Class 对象表示的类的所有已说明的构造子对象数组。
  11 getDeclaredField(String) :返回当前 Class 对象表示的类或接口的指定已说明的一个域对象。
  12 getDeclaredFields() :返回当前 Class 对象表示的类或接口的所有已说明的域对象数组。
  13 getDeclaredMethod(String, Class[]) :返回当前 Class 对象表示的类或接口的指定已说明的一个方法对象。
  14 getDeclaredMethods() :返回 Class 对象表示的类或接口的所有已说明的方法数组。
  15 getField(String) :返回当前 Class 对象表示的类或接口的指定的公有成员域对象。
  16 getFields() :返回当前 Class 对象表示的类或接口的所有可访问的公有域对象数组。
  17 getInterfaces() :返回当前对象表示的类或接口实现的接口。
  18 getMethod(String, Class[]) :返回当前 Class 对象表示的类或接口的指定的公有成员方法对象。
  19 getMethods() :返回当前 Class 对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。
  20 isInstance(Object) :此方法是 Java 语言 instanceof 操作的动态等价方法。
  21 isInterface() :判定指定的 Class 对象是否表示一个接口类型
  22 isPrimitive() :判定指定的 Class 对象是否表示一个 Java 的基类型。
  23 newInstance() :创建类的新实例

新建Test类,测试创造类的Class实例

package day14;

public class Test {
    public static void main(String[] args) {
            Person p = new Person();
            Class clazz = p.getClass();   //clazz对象中就包含对象p所属的Persion类的所有信息
            System.out.println(clazz);

        /**
         * 三种方式创造clazz
         */
        //方式一通过类名.class创建指定类的Class实例
        Class c0 = Person.class;
        //方式二通过一个类的实例对象的getClass()方法,获取对应实例对象的类Class实例
        //Person p = new Person();
        Class c1 = p.getClass();
        //方式三通过Class 的静态方法forName(String className)来获取一个类的Class实例
        //forName(String className) 方法中的参数是你获取的Class实例类的全路径 (包名类名)

        try {
            Class c2 = Class.forName("day14.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }
}

Person类

package day14;

public class Person {
    public String name;
    int age;

}

我们主要通过forName(String className)方式进行操作。

实验

建立两个接口,一个Student类一个Person类,让Student继承Persion类

person类

package day14;

public class Person {
    public String name;
    int age;

}

student类

package day14;

public class Student extends Person implements Move,Study {


    public Student(){
        System.out.println("调用的是public Student()");

    }

    public Student(String school){
        System.out.println("调用的是public Student(String school)");
        this.school=school;
    }

    private Student(String name, int age){
        System.out.println("调用的是private Student(String name, int age)");
        this.name = name;
        this.age = age;
    }

    String school;
    public  void showInfo(){
        System.out.println("学校是 :" + this.school);
    }
    @Override
    public void moveType() {
        System.out.println("学习中学的知识");
    }

    @Override
    public void studyInfo() {
        System.out.println("骑自行车上学");

    }
}

接口1 Studey

package day14;

public interface Study {
    void studyInfo();
}

接口2 Move

package day14;

public interface Move {
    void moveType();
}

开始实验

主程序Test1

package day14;

import java.lang.reflect.Constructor;

public class Test1 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例

            Class superClazz = clazz.getSuperclass();      //获取父类名字
            System.out.println(superClazz.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
输出父类

利用反射获取类的构造方法

下面开始演示getInterfaces()方法
获取类的公有的构造方法

修改Test1类

package day14;

import java.lang.reflect.Constructor;

public class Test1 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例

            Class superClazz = clazz.getSuperclass();      //获取父类名字
            System.out.println(superClazz.getName());
            Class[] interfaces = clazz.getInterfaces();  //获取当前类的所有接口
            for (Class c : interfaces){
                System.out.println("接口 :"  + c.getName());
            }

            Constructor [] cons = clazz.getConstructors();    //获取类的公有的构造方法
            for(Constructor c : cons){
                System.out.println("--------------------------------------------------------------------");
                System.out.println("构造方法名称:" + c.getName());  //获取方法名称
                System.out.println("构造方法名称:" + c.getName() + "构造方法的修饰符是:" + c.getModifiers()); //取得方法的修饰符

                Class [] paramClass = c.getParameterTypes();
                for(Class pc : paramClass){
                    System.out.println("构造方法:" + c.getName() + "的参数类型是:" + pc.getName());
                }
                System.out.println("--------------------------------------------------------------------");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述getDeclaredConstructors()方法


package day14;

import java.lang.reflect.Constructor;

public class Test1 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例

            Class superClazz = clazz.getSuperclass();      //获取父类名字
            System.out.println(superClazz.getName());
		 
		             Constructor [] cons1 =  clazz.getDeclaredConstructors();   //获取类的所有方法,包括共有和私有

            for(Constructor c : cons1){
                System.out.println("--------------------------------------------------------------------");
                System.out.println("构造方法名称:" + c.getName());  //获取方法名称
                //返回数组1代表public 2代表private
                System.out.println("构造方法名称:" + c.getName() + "构造方法的修饰符是:" + c.getModifiers()); //取得方法的修饰符
                Class [] paramClass = c.getParameterTypes();  //获取class的构造方法的参数类型一个数组
                for(Class pc : paramClass){
                    System.out.println("构造方法:" + c.getName() + "的参数类型是:" + pc.getName());
                }
                System.out.println("--------------------------------------------------------------------");
            }

		
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
可以看的出getDeclaredConstructors()方法可以获取private私有方法,而且1代表public方法,2代表private方法.

通过反射的构造方法创建对象

package day14;

import java.lang.reflect.Constructor;

public class Test1 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例

            Class superClazz = clazz.getSuperclass();      //获取父类名字
            System.out.println(superClazz.getName());

				
		        try {
            Object obj = clazz.newInstance();  //相当于调用Student类的1无参公有的构造方法
            Student stu = (Student)obj;


            //Constructor c = clazz.getConstructor(String.class); //指定获取一个有参数并且为String类型的公有的构造方法
            //Student stu1 = (Student)c.newInstance("第一中学"); //newInstance实例化对象,相当于调用public
            //System.out.println(stu1.school);
            /**
             * 通过反射机制可以强制调用私有的构造方法
             *
             */

            //Constructor c =clazz.getDeclaredConstructor(String.class,int.class);
            //指定获取有两个参数,可获取到类的私有构造器(包括带有其他修饰符的构造器),但在使用private的构造器时,必须设置setAccessible()为true,才可以获取并操作该Constructor对象。
            //c.setAccessible(true);  //解除私有的封装,下面就可以对这个私有方法强制调用

            //Student stu = (Student)c.newInstance("张三",12);





        }catch(Exception e){
            e.printStackTrace();
        }


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

构造创建一个对象
public 无参方法:

Object obj = clazz.newInstance();  //相当于调用Student类的1无参公有的构造方法
Student stu = (Student)obj;

public 有参方法

Constructor c = clazz.getConstructor(String.class); //指定获取一个有参数并且为String类型的公有的构造方法
Student stu1 = (Student)c.newInstance("第一中学"); //newInstance实例化对象,相当于调用public
System.out.println(stu1.school);

private 有参方法

Constructor c =clazz.getDeclaredConstructor(String.class,int.class);
指定获取有两个参数,可获取到类的私有构造器(包括带有其他修饰符的构造器),但在使用private的构造器时,必须设置setAccessible()true,才可以获取并操作该Constructor对象。
c.setAccessible(true);     解除私有的封装,下面就可以对这个私有方法强制调用
Student stu = (Student)c.newInstance("张三",12);

反射机制获取类的方法

package day14;

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

public class Test1 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例

            //Method[] ms = clazz.getMethods(); //获取的类的所有的公有的方法
            Method[] ms = clazz.getDeclaredMethods(); //获取类所有的方法包括私有
            for (Method m : ms) {
                System.out.println("方法名:" + m.getName());
                System.out.println("返回值类型:" + m.getReturnType());
                System.out.println("修饰符:" + m.getModifiers());

                Class[] pcs = m.getParameterTypes();//获取方法的参数类型,是一个数组,方法有几个参数,数组就有几个参数
                if (pcs != null && pcs.length > 0) {
                    for (Class pc : pcs) {
                        System.out.println("参数类型:" + pc.getName());
                    }

                }
                System.out.println("-------------------------------------------------------------------------");

            }
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

反射中getMethods 与 getDeclaredMethods 的区别

public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。 public Method[]
getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值