反射
1.Java编译类型
类型 | 特点 |
---|---|
静态编译 | 在编译时确定类型,绑定对象即通过。 |
动态编译 | 在运行时确定类型,绑定对象。体现了就Java的灵活性多态性,降低类之间的耦合性 |
2.Java识别对象和类信息的方式
1)传统的RTTI(run time type identification):运行在编译期间获取所有的类型信息。
2)反射机制:允许在运行期间发现和使用类的信息。前提:Class对象(代表字节码的class)
Class:Java中的一个类,相当于B超的探头,将一个类的方法、变量等其他信息告诉运行的程序
3.什么是反射?
1)Java程序在运行时,对于任何一个类都能获得这个类的信息(属性、方法、修饰符),还可以在运行时实例化对象,调用方法及设置属性。
2)举例:
– JDBC(数据库访问技术)、spring、 mybatis、 jackson、 GSON
– 一个类中有成员方法,变量,构造器,利用反射可以对此类进行解剖,把各个组成部分映射为一个个对象。
反射原理如下:
4.反射的优点
1)使用反射可以赋予jvm动态编译的能力,否则类的元数据信息只能使用静态编译的方式来实现。当我们写的程序在运行时,需要动态加载,提升了服务器的性能。
2)Eg:
– 项目开发中使用的数据库是MySQL或者Oracle,需要动态的根据实际情况加载相应的数据库驱动类。
– spring中配置的各种JavaBeen是以xml形式的配置文件来存放,使用到哪些类就通过spring容器会根据你的需求动态加载到对应的类。
3)使用Java的反射机制可以增加程序的灵活性,避免将程序写死。
5.实现反射的类
1)位于Java.lang.reflection包中
2)Class类:表示为一个类
3)Method类:表示为类的方法
4)Field类:表示为类的成员属性
5)Constructor:表示为类的构造器
6.Class类
1)Java.lang.Class:是反射的源头
2)创建一个类的时候首先通过编译生成class文件,之后通过jvm的类加载器,将class文件加载到jvm内存中,此时会创建一个Class对象。这个Class对象只会加载一次。
有了此Class对象后可以进行如下操作:
– 创建对应运行类的对象(掌握)
– 获取运行时类的完整结构(属性、方法、构造器、异常、注解、访问修饰符)
– 调用对应的运行时类指定的结构(属性、方法、构造器)(掌握)
// 使用反射的方式创建对象,访问类的结构(属性方法)
@Test
public void test2() throws Exception {
// 获取Person类的Class类的对象
Class<Person> clazz = Person.class;
// 创建clazz对应的运行时类Person对象
Person p = (Person)clazz.newInstance();
System.out.println(p);
// 通过反射获取运行时类的属性
Field f1 = clazz.getField("name");
//Field f2 = clazz.getField("age");error
// 设置属性
f1.set(p, "jack");
//f2.set(p, 25);error
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");
}
7.获取Class对象的方式
// 获取Class对象的方式
@Test
public void test3() throws ClassNotFoundException {
// 1.调用运行时类本身的class属性
Class clazz1 = Person.class;
// 获取类的完整路径(全限定名或完全限定名)
System.out.println(clazz1.getName());
// 2.通过类对象的getClass()方法
Person person = new Person();
Class clazz2 = person.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());
}
补充:
Html:超文本标记语言 hl div span 用来显示数据
XML:可扩展标记语言 自定义标签 (dtd xsd进行约束) 用来存储数据