工欲善其事必先利其器,反射你真的掌握了吗?本文详细给你讲解

for (int i = 0; i < 100000000; i++) {

hi.invoke(o);

}

long end = System.currentTimeMillis();

System.out.println(“反射调用执行的时间:” + (end - start));

}

/**

  • 反射方式调用

*/

public static void fun3() throws Exception{

long start = System.currentTimeMillis();

Class<?> aClass = Class.forName(“com.bobo.util.reflection.domain.Cat”);

Object o = aClass.newInstance();

Method hi = aClass.getMethod(“hi”);

hi.setAccessible(true); // 取消反射调用方法时 取消访问检查

for (int i = 0; i < 100000000; i++) {

hi.invoke(o);

}

long end = System.currentTimeMillis();

System.out.println(“优化-反射调用执行的时间:” + (end - start));

}

输出结果

传统方法掉执行的时间:3

反射调用执行的时间:114

优化-反射调用执行的时间:80

3 Class类介绍


3.1 基本介绍

1、Class也是类,因此也继承Object类

在这里插入图片描述

2、Class类对象不是new出来的,而是系统创建的

// 传统对象获取

/**

  • new Cat(); 对象的时候会直接接入 ClassLoader的 loadClass方法中
    
  • public Class<?> loadClass(String name) throws ClassNotFoundException {
    
  •     return loadClass(name, false);
    
  • }
    

*/

// Cat cat = new Cat();

// 通过反射方式获取对象

/**

  • 在反射的情况下,仍然是通过ClassLoader类加载的Class对象

  • public Class<?> loadClass(String name) throws ClassNotFoundException {
    
  •     return loadClass(name, false);
    
  • }
    

*/

Class<?> aClass = Class.forName(“com.bobo.util.reflection.domain.Cat”);

Object o = aClass.newInstance();

3、对于某个类的Class类对象,在内存中只有一份,因为类只加载一次

​ 在上面的案例里面其实是可以验证的

Class<?> aClass1 = Class.forName(“com.bobo.util.reflection.domain.Cat”);

Class<?> aClass2 = Class.forName(“com.bobo.util.reflection.domain.Cat”);

System.out.println(aClass1.hashCode());

System.out.println(aClass2.hashCode());

结果输出

460141958

460141958

4、每个类的实例都会记得自己是由哪个Class实例所生成的

5、通过Class可以完整地得到一个类的完整结构,通过相关的API实现

在这里插入图片描述

6、Class对象是存储在堆中的

7、类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括方法代码,变量名,方法名、访问权限等)

在这里插入图片描述

3.2 Class类的常用方法

直接通过案例来说明

public static void main(String[] args) throws Exception{

String classAllName = “com.bobo.util.reflection.domain.Car”;

// 1.获取Car类对应的Class对象

Class<?> aClass = Class.forName(classAllName);

// 2.输出aClass

System.out.println(aClass);// 显示aClass对象是哪个类的Class对象

System.out.println(aClass.getClass()); // 输出 运行类型 com.lang.Class

// 3.获取包名

System.out.println(aClass.getPackage().getName());

// 4.得到全类名

System.out.println(aClass.getName());

// 5.通过类对象创建实例

Car car = (Car) aClass.newInstance();

System.out.println(car);

// 6.通过反射获取属性

Field brand = aClass.getField(“brand”);

System.out.println(brand.get(car));

// 7.通过反射给属性设置值

brand.set(car,“奔驰”);

System.out.println(brand.get(car));

// 8.获取所有属性的值

Field[] fields = aClass.getFields();

for (Field field : fields) {

System.out.println(field.get(car));

}

}

输出结果为:

class com.bobo.util.reflection.domain.Car

class java.lang.Class

com.bobo.util.reflection.domain

com.bobo.util.reflection.domain.Car

com.bobo.util.reflection.domain.Car@1b6d3586

BMW

奔驰

奔驰

400000.0

白色

3.3 Class类对象的获取方式

1.Class.forName()

使用的前提条件是已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName方法获取,可能抛出ClassNotFoundException。

Class<?> aClass1 = Class.forName(“com.bobo.util.reflection.domain.Cat”);

应用的场景:多用于配置文件,读取类全路径,加载类

2.具体类.class

如果已经知道了具体的类,可以通过类的class属性类获取,该方式最为安全可靠,程序性能最高

Class cls1 = Car.class;

应用场景:多用于参数传递,比如通过反射得到对应构造器对象。

3.对象.getClass

已经获取了某个类的实例,调用该实例的getClass()方法获取Class对象,

Class cls = Car.getClass();

应用场景:通过创建好的对象,获取Class对象

4.其他方式

ClassLoader cl = 对象.getClass().getClassLoader();

Class cls = cl.loadClass(“类的全类名”);

5.基本数据类型

对于基本数据类型通过如下方式来获取对应的Class对象

Class cls = 基本数据类型.class;

Class cls = int.class;

6.包装类

基本数据类型对应的包装类可以通过.TYPE得到Class类对象

Class cls = Integer.TYPE;

在这里插入图片描述

3.4 有Class对象的类型

1、外部类,成员内部类,静态内部类,局部内部类,匿名内部类

2、interface:接口

3、数组

4、enum:枚举

5、annotation:注解

6、基本数据类型

7、void

public static void main(String[] args) {

Class cls1 = String.class;// 外部类

Class cls2 = List.class;// 接口

Class<Integer[]> cls3 = Integer[].class;// 数组

Class<float[][]> cls4 = float[][].class; // 二维数组

Class cls5 = Resource.class; // 注解

Class<Thread.State> cls6 = Thread.State.class; // 枚举

Class cls7 = long.class; // 基本数据类型

Class cls8 = void.class; // void 数据类型

Class cls9 = Class.class; // Class

System.out.println("cls1 = " + cls1);

System.out.println("cls2 = " + cls2);

System.out.println("cls3 = " + cls3);

System.out.println("cls4 = " + cls4);

System.out.println("cls5 = " + cls5);

System.out.println("cls6 = " + cls6);

System.out.println("cls7 = " + cls7);

System.out.println("cls8 = " + cls8);

System.out.println("cls9 = " + cls9);

}

输出结果

cls1 = class java.lang.String

cls2 = interface java.util.List

cls3 = class [Ljava.lang.Integer;

cls4 = class [[F

cls5 = interface javax.annotation.Resource

cls6 = class java.lang.Thread$State

cls7 = long

cls8 = void

cls9 = class java.lang.Class

4.类加载


4.1 类加载概述

反射机制是Java实现动态语言的关键,也就是通过反射实现类动态加载

  1. 静态加载:编译时加载相关的类,如果没有则报错,依赖性太强

  2. 动态加载:运行时加载需要的类,如果运行时不用该类,则不报错,降低了依赖性

举例说明:

public static void main(String[] args) throws Exception{

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

Java面试核心知识点笔记

其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

Java中高级面试高频考点整理

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

最后分享Java进阶学习及面试必备的视频教学

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

转存中…(img-AU7eZ7GY-1710420005403)]
[外链图片转存中…(img-yrtfB1un-1710420005403)]
[外链图片转存中…(img-AvN1GmPI-1710420005404)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-YBiIT755-1710420005404)]

Java面试核心知识点笔记

其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

[外链图片转存中…(img-C1CmC6ZJ-1710420005405)]

Java中高级面试高频考点整理

[外链图片转存中…(img-CwuPNOp0-1710420005406)]

[外链图片转存中…(img-58AMO2AR-1710420005406)]

最后分享Java进阶学习及面试必备的视频教学

[外链图片转存中…(img-PRhYzRyc-1710420005406)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值