反射的三种方式/得到Class对象的三种方法

1、Object类的getClass()方法

任意Java对象都具备这个方法。

在顶层父类Object 中,返回内容形式为:class 包名.类名

public final native Class<?> getClass();

native关键字修饰,无方法体,由底层JVM调用c/c++的代码实现。

类的加载:.class字节码文件加载到内存,并创建一个java.lang.Class对象的过程。

主要是由类加载器来完成。

java.lang.Class类就是用来封装被装入JVM中的类/接口的信息。每个类(型)都有一个Class对象。

public static void main(String[] args) {
        Student student = new Student();
        Class<? extends Student> clazz = student.getClass();
        System.out.println("clazz = " + clazz);
        System.out.println("clazz.getName() = " + clazz.getName());
        System.out.println("clazz.getSimpleName() = " + clazz.getSimpleName());
    }

//输出
clazz = class com.xiexie.demo.entity.Student
clazz.getName() = com.xiexie.demo.entity.Student
clazz.getSimpleName() = Student

2、类名.class

Class<Student> studentClass = Student.class;

3、Class类的静态方法:forName()

有好几个重载方法

@CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

 可以看到最终是调用native修饰的方法。

private static native Class<?> forName0(String name, boolean initialize,
                                            ClassLoader loader,
                                            Class<?> caller)
        throws ClassNotFoundException;
try {
            Class<?> aClass = Class.forName("com.xiexie.demo.entity.Student");
            System.out.println("aClass.getName() = " + aClass.getName());
            System.out.println("aClass.getSimpleName() = " + aClass.getSimpleName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

//输出:
aClass.getName() = com.xiexie.demo.entity.Student
aClass.getSimpleName() = Student

拓展: 

//获得类加载器
ClassLoader classLoader = clazz.getClassLoader();
classLoader.getResourceAsStream() 返回InputStream,常用来读取资源文件。

//获取所有public 修饰的构造方法。包括父类中的构造方法。
Constructor<?>[] constructors = clazz.getConstructors();
//前面Student类仅使用@Data注解。constructors 遍历后输出
constructor = public com.xiexie.demo.entity.Student()

// 获取指定参数类型所对应的构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)
// 打印输出:public com.xiexie.demo.entity.Student()  无参构造
Constructor<? extends Student> constructor = clazz.getConstructor(null);
//getDeclaredConstructors() 获得本类的所有声明的构造方法;包括私有构造
//getDeclaredConstructor(Class<?>... parameterTypes) 根据参数获取
Class<?> clazz = Class.forName("com.xiexie.demo.entity.Student");
            Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println("declaredConstructor = " + declaredConstructor);
            }
//Student类去掉lombok注解,都设置成私有构造。 输出如下:
declaredConstructor = private com.xiexie.demo.entity.Student()
declaredConstructor = private com.xiexie.demo.entity.Student(java.lang.String,java.lang.Integer,java.lang.String,java.lang.String)

获得构造方法,创建对象

//1、获取无参构造,创建对象
Constructor<? extends Student> constructor = clazz.getConstructor(null);
Student student1 = constructor.newInstance(null);
System.out.println("student1 = " + student1);
//输出
student1 = Student(name=null, age=null, stuNum=null, address=null)

//2、获取有参构造,创建对象。Student类加上了@NoArgsConstructor、@AllArgsConstructor注解
Constructor<? extends Student> constructor = clazz.getConstructor(String.class,
                Integer.class,String.class,String.class);
System.out.println("constructor = " + constructor);
Student student1 = constructor.newInstance("张三",18,"001","深圳");
System.out.println("student1 = " + student1);
//输出:
constructor = public com.xiexie.demo.entity.Student(java.lang.String,java.lang.Integer,java.lang.String,java.lang.String)
student1 = Student(name=张三, age=18, stuNum=001, address=深圳)

 私有构造,创建对象

Class<?> clazz = Class.forName("com.xiexie.demo.entity.Student");
        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, Integer.class, String.class, String.class);
Object obj = constructor.newInstance("张三", 18, "001", "深圳");
System.out.println("obj = " + obj);

//输出异常。私有构造private
java.lang.IllegalAccessException: Class com.xiexie.demo.Test can not access a member of class com.xiexie.demo.entity.Student with modifiers "private"

//暴力访问,取消访问检查。
constructor.setAccessible(true);
Object obj = constructor.newInstance("张三", 18, "001", "深圳");
System.out.println("obj = " + obj);
//能正常输出
obj = Student{name='张三', age=18, stuNum='001', address='深圳'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值