总结:在编译时,如果明确知道要创建什么类的对象,一般用new,其效率比反射要高很多。但当编译时期无法确定要用什么类时,就需要用反射了。
通俗解释:比如开发一款吃鸡游戏,玩家需要在地上捡枪进行射击,但是开发的时候,并不知道玩家捡的枪是什么,也就无法在开发的时候去new具体的对象,这时候就要用反射了。
1.new对象与反射创建对象效率对比
//new对象
Instant start = Instant.now();
for (int i = 1; i <= 1000000000; i++) {
User user = new User();
}
Instant end = Instant.now();
long duration = Duration.between(start, end).toMillis();
System.out.println("new创建对象消耗时间为:" + duration + "毫秒");
System.out.println("========================================");
//反射创建对象
Class<User> userClass = User.class;
Instant start2 = Instant.now();
for (int i = 1; i <= 1000000000; i++) {
User user = userClass.newInstance();
}
Instant end2 = Instant.now();
long duration2 = Duration.between(start2, end2).toMillis();
System.out.println("反射创建对象消耗时间为:" + duration2 + "毫秒");
结果为:
new创建对象消耗时间为:15毫秒
========================================
反射创建对象消耗时间为:2078毫秒
可以看出,new对象的效率更高。
2.反射动态创建对象的例子
假设开发一款吃鸡游戏,有三种枪:AKM、M416、KAR98K,每种枪都有一个射击方法shoot()。
(1)创建三个实体类
public class AKM {
public void shoot() {
System.out.println("模拟使用AKM进行射击:dongdongdong~~~");
}
}
public class KAR98K {
public void shoot() {
System.out.println("模拟使用KAR98K进行射击:BOMMMMM~~~");
}
}
public class M416 {
public void shoot() {
System.out.println("模拟使用M416进行射击:biubiubiu~~~");
}
}
(2)模拟反射动态创建对象的使用场景 --- 根据用户拾取的枪械,执行对应的shoot方法。
public class Test {
public static void main(String[] args) throws Exception {
//此处用控制台输入 模拟 玩家捡到的枪
System.out.println("请输入拾取的枪械名称:");
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String gunName = scanner.next();
String className = "com.muma.domain." + gunName;
Class<?> clazz = Class.forName(className);
//通过反射创建对象 ---> 编译时无法确定要创建什么对象,无法用new
Object gun = clazz.newInstance();
//执行相应的射击方法
Method shoot = clazz.getMethod("shoot");
shoot.invoke(gun);
System.out.println("请输入拾取的枪械名称:");
}
}
}
结果如下:
请输入拾取的枪械名称:
AKM
模拟使用AKM进行射击:dongdongdong~~~
请输入拾取的枪械名称:
M416
模拟使用M416进行射击:biubiubiu~~~
请输入拾取的枪械名称:
KAR98K
模拟使用KAR98K进行射击:BOMMMMM~~~