java-反射基础入门

    科技2024-04-15  11

    反射

    反射是java中提供的一种机制,它允许我们在程序运行的时候,动态获取一个类中的基本信息,并且可以调用类中的属性,方法,构造器.

    public class Student{ private String name; int age; public static int num; public Student(){} public Student(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String sayHello(String name){ return "hello! "+name; } }

    我们除了使用眼睛看到这个类中的属性方法构造器之外,在代码运行的时候,也可以通过反射机制获取到这个类中的属性,方法,构造器,已经调用构造器和方法.

    Class c = Class.forName("com.briup.demo.Student"); Field[] fields = c.getDeclaredFields(); for(Field f : fields){ System.out.println("属性的修饰符:"+Modifier.toString(f.getModifiers())); System.out.println("属性的类型:"+f.getType().getName()); System.out.println("属性的名称:"+f.getName()); System.out.println("---------------------"); }

    Class类型

    java.lang.Class 是API中提供的一个类,它可以表示java中所有的类型,包括基本类型和引用类型.

    getClass方法的返回类型就是Class,所以obj.getClass();这句代码的含义就是,返回obj引用在运行时所指向对象的实际类型.

    Class类型可以表示基本类型,数组类型,接口类型,类类型,每种类型加载到内存之后,都会在内存中生成一个Class类型对象,这个对象就代表这个具体的java类型,并且保存这个类型中的基本信息.

    注意:java中的每种类型都有且只有唯一的一个Class类型对象与之对应!并且在类加载的时候自动生成

    获取基本类型的Class对象

    只有一种: Class c = int.class;

    获取接口类型的Class对象有两种方法

    Class c1 = Action.class;

    Class c2 = Class.forName(“com.briup.demo.Action”);

    获取数组类的Class对象有两种方法

    Class c1 = int[].class; int[] arr = new int[4];Class c2 = arr.getClass();

    获取类类型的Class对象有三种方法

    Class c1 = Student.class;Class c2 = Class.forName(“com.briup.demo.Student”);Student stu = new Student(); Class c3 = stu.getClass();

    可以看出,获取一个类型Class对象的途径一般有三种

    使用类型名称直接获取-使用Class类中的静态方法forName获取使用对象调用getClass方法获取

    获取类中声明的属性

    获取类中public修饰的属性,也包括从父类中继承的public属性

    Field[] getFields()

    Field getFiled(String name)

    获取类中声明的属性(包含私有的),但是不能获取从父类中继承过来的属性 Field[] getDeclaredFields()Field getDeclaredField(String name)

    java.lang.reflect.Field 表示类中的属性

    获取类中的方法

    获取当前类中的public方法,包含从父类中继承的public方法 Method[] getMethods()Method getMethod(String name,Class<?>… parameterTypes) 获取当前类中声明的方法(包含私有的),但是不能获取从父类中继承过来的方法 Method[] getDeclaredMethods();Method getDeclaredMethods(String name,Class<?>… parameterTypes);

    获取类中声明的构造器

    获取当前类中的public构造器

    public Constructor[] getConstructors()

    public Constructor getConstructor(Class… parameterTypes)

    获取当前类中的所有构造器,包含私有

    public Constructor[] getDeclaredConstructors()

    public Constructor getDeclaredConstructor(Class… parameterTypes)

    反射访问属性

    public static void main(String[] args)throws Exception { Student stu = new Student(); Class c = stu.getClass(); //获取类中名字叫name的属性 Field f1 = c.getDeclaredField("name"); //设置私有属性可以被访问,否则报错 f1.setAccessible(true); //用反射的方式,给指定对象的name属性赋值 //相当于之前的stu.name = "tom"; f1.set(stu,"tom"); //用反射的方式,获取这个属性的值 //相当于之前的stu.name System.out.println(f1.get(stu)); System.out.println("----------------------"); //获取类中名字叫age的属性 Field f2 = c.getDeclaredField("age"); //用反射的方式,给指定对象的age属性赋值 //相当于之前的stu.age = 20; f2.set(stu,20); //用反射的方式,获取这个属性的值 //相当于之前的stu.age System.out.println(f2.get(stu)); System.out.println("----------------------"); //获取类中名字叫num的属性 //4.6 反射调用方法 //注意, public Object invoke(Object obj, Object... args) //obj,表示要调用哪个对象的方法,如果是静态方法,可以传null //args,可变参数,表示要调用的方法的参数列表 m.invoke(obj,null) 中的m,就是通过Class对象获取到的类中的某一个指定的方法 //4.7 反射创建对象 //使用反射的方式可以创建对象,也就是需要反射调用构造器。 Field f3 = c.getDeclaredField("num"); //用反射的方式,给静态属性num赋值,不需要对象 //相当于之前的Student.num = 99; f3.set(null,99); //用反射的方式,获取这个静态属性的值,不需要对象 //相当于之前的Student.num System.out.println(f3.get(null)); }

    反射调用方法

    public static void main(String[] args)throws Exception { Student stu = new Student(); Class c = stu.getClass(); //获取类中的toString方法,没有参数,这是从父类继承的方法 Method m1 = c.getMethod("toString", null); //反射的方式,调用stu对象中的这个方法,没有参数,并接收执行结果 //相当于之前的:Object result = stu.toString(); Object result = m1.invoke(stu,null); //输出执行结果 System.out.println(result); System.out.println("-------------------"); //获取类中的sayHello方法,需要一个String类型的参数,这是自己定义的方法 Method m2 = c.getMethod("sayHello", String.class); //反射的方式,调用stu对象中的这个方法,参数是"tom",并接收执行结果 //相当于之前的:Object result = stu.sayHello("tom"); result = m2.invoke(stu,"tom"); //输出执行结果 System.out.println(result); }

    反射调用构造器

    无参构造器 public static void main(String[] args)throws Exception { Class c = Student.class; //默认调用类中的无参构造器来创建对象 //相当于之前的:Object obj = new Student(); Object obj = c.newInstance(); System.out.println(obj); } 有参构造器 public static void main(String[] args)throws Exception { Class c = Student.class; //获取类中的俩参构造器 Constructor constructor = c.getConstructor(String.class, int.class); //调用有参构造器创建对象,并传入对应的参数值 //相当于之前的:Object obj = new Student("tom",20); Object obj = constructor.newInstance("tom",20); System.out.println(obj); }
    Processed: 0.018, SQL: 12