1.java中的编译类型
* ①.静态编译:在编译时确定类型,绑定对象即通过。
* ②.动态编译:在运行时确定对象类型,绑定对象。体现了java的灵活性和多态性。降低类之间的耦合性。
2.java识别对象和类信息的方式
* ①.RTTI(run time type identification):允许在编译期间获取所有的类型信息。
* ②.反射机制:允许在运行期间发现和使用类的信息 前提:Class对象(代表字节码的Class)
* Class:Java中一个类 相当于B超的探头,将一个类的方法,变量 等其他信息告诉运行的程序
3.什么是反射?
* java程序在运行时,对于任何一个类都能获取这个类的信息(属性、方法、修饰符),还可以在运行时实例化对象,调用方法及设置属性
* 举例:JDBC(数据库访问技术)、Spring、Mybatis、jackson、GSON
* 举例:一个类中有成员变量、方法、构造器等信息,利用反射可以对此类进行解剖,把各个组成部分映射成一个个对象
4.为什么需要使用反射?
* ①.使用反射可以赋予JVM动态编译的能力,否则类的元数据信息只能使用静态编译的方式来实现
* 当我们写的程序在运行时,需要动态的加载,提升了服务器的性能。
* eg:项目开发中使用的数据库是mysql或者oracle,需要动态的根据实际情况加载相应的数据库驱动类
* eg:spring中配置各种javaBean,是以XML形式的配置文件来存放,使用到哪些类就通过spring容器会根据你的需求动态加载对应的类
* ②.使用java的反射机制可以增加程序的灵活性,避免将程序写死。
5.实现反射的类
* 实现反射的类都位于java.lang.reflect包中
* ①.Class类:表示为一个类
* ②.Method类:表示为类的方法
* ③.Field类:表示为类的成员属性
* ④.Constructor:表示为类的构造器
6.Class类
* java.lang.Class:反射的源头
* 创建一个类,首先通过编译生成对应的class文件,之后通过JVM的类加载器(ClassLoader),将class文件加载到JVM内存中
* 此时会创建一个Class对象。Class对象只会加载一次
* 有了此class对象后可以进行如下操作:
* ①.创建对应运行类的对象(掌握)
* ②.可以获取对应运行时类的完整结构(属 性、方法、构造器、异常注解、访问修饰符)
* ③.调用对应的运行时类指定的结构(属性、方法、构造器)(掌握)
使用反射的方式创建对象,访问类的结构(属性、方法)
@Test
public void test2() throws Exception{
// 获取Person类的Class类对象
Class clazz = Person.class;
// 创建clazz对应的运行时类的Person对象
Person p =(Person)clazz.newInstance();
System.out.println(p);
// 通过反射获取运行时类的指定属性
Field f1 = clazz.getField("name");
// 设置属性
f1.set(p, "jack");
System.out.println(p);
Field f2 = clazz.getDeclaredField("age");
// 设置允许访问
f2.setAccessible(true);
f2.set(p, 25);
System.out.println(p);
// 通过反射获取运行时指定的方法
Method m1 = clazz.getMethod("show");
// 通过反射调用方法(指明实例对象和参数值)
m1.invoke(p);
Method m2 = clazz.getMethod("display", String.class);
m2.invoke(p, "china");
}
获取Class对象的方式
public void test3() throws ClassNotFoundException {
// 1.调用运行时类本身的class属性
Class clazz1 = Person.class;
// 获取完整路径(全限定名或者完全限定名)
System.out.println(clazz1.getName());
// 2.通过类对象的getClass()方法
Person p = new Person();
Class clazz2 = p.getClass();
System.out.println(clazz2.getName());
// 3.通过Class.forName()静态方法
Class<?> clazz3 = Class.forName("com.hpe.reflect.Person");
System.out.println(clazz3.getName());
// 4.通过类加载器(ClassLoader) 了解
ClassLoader classLoader = this.getClass().getClassLoader();
Class<?> clazz4 = classLoader.loadClass("com.hpe.reflect.Person");
System.out.println(clazz4.getName());
Class clazz5 = String.class;
System.out.println(clazz5.getName());
Class clazz6 = int.class;
System.out.println(clazz6.getName());
}