JavaSE基础二十五:反射、获取反射对象、反射中有关Class类、Filed类、Method类、Constructor类的方法

一、反射

1.类型信息
Java让我们在运行时识别类和对象的信息,主要有两种方式:一种是传统的RTTI(Run-Time Type Identification),它假定我们在编译期已经知道了所有的类型信息;另一种是反射机制,它允许我们在运行时发现和使用类的信息,使用的前提条件是:必须先得到类的字节码的Class,Class类用于表示.class文件,也就是字节码文件

2.反射概述
Java反射机制是指,在运行状态中,能够知道这个类所有的属性和方法。对于任意一个对象,都能够调用它的任意一个属性和方法,这种动态获取的信息以及动态调用对象的方法的功能叫做Java的反射机制

反射就是把类中的各个成分映射成一个个的对象

3. .class文件的唯一性
拿Student类举例
当我们第一次创建Student类的对象时,JVM会将Student类的字节码文件(Student.class)加载进内存,然后在堆内存开辟空间。
当我们想再次创建Student对象时,JVM会先去内存中寻找是否有Student类的字节码文件(Student.class),如果有,就不会再去加载Student类的字节码文件(Student.class),直接使用。这说明,每个类的字节码文件(.class)再内存的存在都是唯一的。

在一个万物皆对象的Java世界中,我们同样也可以获得类的.class文件的对象,然后通过这个对象去创建对象,这样就可以不通过new创建某个类的对象了

4.与反射有关的类

类名用途
Class代表类的实体,在运行的Java应用程序中表示类和接口
Filed代表类的成员变量
Method代表类的方法
Constructor代表类的构造方法

5.获得Class对象的方法
注意:是获得Class对象的方式,不是创建某类对象的方式
以Person类为例

Person person = new Person (); 

方式一:
Class class1 = person.getClass();

方式二:    我们一般以这种方式创建Class对象
Class class2 = Class.forName("包名.Person ");

方式三:
Class class3 = Person .class;

方式四:该方法只针对于包装类
Class type = Integer.TYPE;

6.有关Class类的方法

方法用途
getName()获得类的完整路径名字:包名 + 类名
getSimpleName()获取类名
newInstance()创建某类对象

7.有关Filed类的方法

方法用途
getFields()获得全部public的属性,存在Field[ ]数组中
getDeclaredFields()获得全部的属性,包括私有,存在Field[ ]数组中
getField()获得指定public的属性对象,返回的是Field对象
getDeclaredField()获取指定的属性,包括私有,返回的是Field对象

8.有关Method类的方法

方法用途
getMethods()获得当前类和它继承的类的public方法,不包括该类的构造方法
getDeclaredMethods()获得当前类的所有方法,包括私有,不包括该类的构造方法
getMethod(String name, Class…<?> parameterTypes)获得该类某个public方法,不包括该类的构造方法
getDeclaredMethod(String name, Class…<?> parameterTypes)获得该类某个方法,包括私有,不包括该类的构造方法

9.有关Constructor类的方法

方法用途
getConstructors()获得该类的所有public构造方法
getDeclaredConstructors()获得该类所有构造方法,包括私有
getConstructor(Class…<?> parameterTypes)获得该类中与参数类型匹配的public构造方法
getDeclaredConstructor(Class…<?> parameterTypes)获得该类中与参数类型匹配的构造方法,包括私有

二、反射代码

package czx.xupt.annotation;		//注意包名 后面会用到

public class User1 {
    private String name;
    private int age;

    public User1() {
    }

    public User1(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Demo1_Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    	//user 的 Class 对象
        Class class1 = Class.forName("czx.xupt.annotation.User1"); 

        System.out.println("===========================================");
        System.out.println(class1.getName()); //全类名  包名 + 类名
        System.out.println(class1.getSimpleName()); //类名

        //获得字段 
        System.out.println("===========================================");
        Field[] fields = class1.getFields(); //只能获得public的属性
        System.out.println(fields.length);

        Field[] fields2 = class1.getDeclaredFields(); //返回全部的属性,可以获得私有的
        System.out.println(fields2.length);

        for (Field field : fields2) {
            System.out.println("field:\t"+field);
        }

        Field name = class1.getDeclaredField("name"); //获取指定的字段
        System.out.println(name);

        //获得方法 : 执行 invoke
        System.out.println("===========================================");
        Method[] methods = class1.getMethods(); //返回当前类和被继承的类的public方法
        System.out.println(methods.length);

        for (Method method : methods) {
            System.out.println("methods: "+method);
        }

        Method[] declaredMethods = class1.getDeclaredMethods(); //获得当前类的所有方法
        System.out.println(declaredMethods.length);

        for (Method method : declaredMethods) {
            System.out.println("declaredMethods: "+method);
        }

        System.out.println("=========================================");
        //如果只获得方法的名字就会有问题: 方法有重载(参数类型)
        Method setName = class1.getMethod("setName",String.class);
        Method setAge = class1.getMethod("setAge",int.class);
        System.out.println(setName);
        System.out.println(setAge);

        //获得构造器 : 创建对象  newInstance()
        System.out.println("===========================================");
        //获得所有public的构造器
        Constructor[] constructors = class1.getConstructors();  
        System.out.println(constructors.length);
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
	//获得所有的构造器
        Constructor[] constructors2 = class1.getDeclaredConstructors();  
        System.out.println(constructors2.length);
        for (Constructor constructor : constructors2) {
            System.out.println(constructor);
        }

        System.out.println("========================================");
        //获得指定的构造器: 重载,只能通过参数名判断  null
        Constructor constructor = class1.getConstructor(null);
        Constructor constructor2 = class1.getConstructor(String.class,int.class);
        System.out.println(constructor);
        System.out.println(constructor2);
    }
}
public class Demo2_Test {
    public static void main(String[] args) throws Exception {
        Class c1 = Class.forName("czx.xupt.annotation.User1");
        //创建对象,new 
        System.out.println("==========================================");
        User1 user1 = (User1) c1.newInstance(); //创建对象
        System.out.println(user1); //默认调用的是无参构造器

        System.out.println("==========================================");
        //通过指定构造器创建对象! 
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class );
        User1 user2 = (User1) declaredConstructor.newInstance("czx", 23 );
        System.out.println(user2);

        System.out.println("==========================================");
        User1 user3 = (User1) c1.newInstance();
        //1. 获得你要操作的方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //2. 通过invoke方法执行方法
        //一个class可能存在多个对象, 这个方法需要找到是那个对象使用的,给他赋值;
        setName.invoke(user3,"czx1");
        System.out.println(user3.getName());

        //获得字段
        System.out.println("==========================================");
        User1 user4  = (User1) c1.newInstance();
        Field name = c1.getDeclaredField("name"); //反射无法直接破坏私有的
        //显示调用setAccessible为true,则可以访问private方法!
        name.setAccessible(true);
        name.set(user4,"czx2");
        System.out.println(user4.getName());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值