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.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.1 类加载概述
反射机制是Java实现动态语言的关键,也就是通过反射实现类动态加载
-
静态加载:编译时加载相关的类,如果没有则报错,依赖性太强
-
动态加载:运行时加载需要的类,如果运行时不用该类,则不报错,降低了依赖性
举例说明:
public static void main(String[] args) throws Exception{
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
Java面试核心知识点笔记
其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。
Java中高级面试高频考点整理
最后分享Java进阶学习及面试必备的视频教学
转存中…(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)]