反射的概念
反射的概念是由Smith在1982年首次提出的,主要是指程序在执行的时候可以访问、检测和修改它本身状态(变量)或行为(方法)的一种能力。(对于Java程序来说,状态和行为就是类的变量和方法)
反射的特点
Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。这样的特点就是反射。
反射是框架的灵魂!
反射的灵魂是字节码文件对象。反射其实就是将运行时一个类的各个部分重新拼装成一个类的过程
作用(官方)
-
在运行时判断任意一个对象 所属的类(判断connection对象,所属的类)
-
在运行时构造任意一个类的对象(不用new,直接使用字节码文件对象就能创建对象)
-
在运行时判断任意一个类所具有的成员变量和方法
-
在运行时调用任意一个对象的方法。通过反射甚至可以调用到private方法。
-
生成动态代理(代理模式中的一种)
作用(通俗)
假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。Java的反射机制 它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。大家都用过eclipse和idea。当我们构建出一个对象的时候,去调用该对象的方法和属性的时候。一按点,编译工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供用户进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审。
获得字节码文件的三种方式(没有字节码文件,反射就是空谈)
-
对象.getClass() connection.getClass()
-
使用 Class 类的 forName() 静态方法, 全路径类名, 该方法最常使用 Class.forName("com.mysql.jdbc.Driver");
-
使用“类型名.class” 类似于User.class
生成对象(一定要掌握 newInstance())
-
使用无参构造方法,只需调用这个类对应的 Class对象 的 newInstance() 方法
-
使用带参数的构造函数生成对象
-
Class对象调用getConstructor(参数类型的Class对象),获取带参数的构造函数;
-
构造函数调用 newInstance(参数) 生成对象
-
Class 对象的方法一览
-
public String getName()
-
返回此 Class 对象所表示的实体的全限定名称。
-
-
public String getSimpleName()
-
返回此 Class 对象所表示的实体的全限定名称。
-
-
public Field[] getFields()
-
返回此 Class 对象所表示的实体的所有公共属性。
-
-
public Field[] getField(String name)
-
返回此 Class 对象所表示的实体的指定属性名称的公共属性。
-
-
public Field[] getDeclaredFields()
-
返回此 Class 对象所表示的实体的所有属性, 包括私有属性,但不包括继承父类的属性。
-
-
public Method[] getMethods()
-
返回此 Class 对象所表示的实体的所有公共方法。
-
-
public Method[] getDeclaredMethods()
-
返回此 Class 对象表示的实体的所有方法,包括私有方法,但不包括继承父类的方法。
-
-
public Method getMethod(String name, Class... parameterTypes)
-
返回此 Class 对象所表示的实体的指定公共成员方法,
-
name指定方法名称,parameterTypes指定方法参数类型
-
-
-
public Constructor[] getConstructors()
-
返回此 Class 对象所表示的类的所有公共构造方法。
-
-
public Constructor[] getDeclaredConstructors()
-
返回此 Class 对象表示的类声明的所有构造方法, 包括私有构造方法。
-
-
public Constructor<T> getDeclaredConstructor(Class... parameterTypes)
-
返回此 Class 对象所表示的类的指定的构造方法。
-
-
public Class<? super T> getSuperclass()
-
返回此 Class 对象所表示的实体的超类的 Class。
-
-
public Class[] getInterfaces()
-
确定此 Class 对象所表示的类实现的接口。
-
-
public T newInstance()
-
创建此 Class 对象所表示的类的一个新实例。
-
类必须有一个无参构造方法
-
-
public Package getPackage()
-
获取此类的包。 【String [Package].getName()】
-
-
public int getModifiers()
-
返回此类或接口以整数编码的 Java 语言修饰符。【String Modifier.toString(int)】
-
-
public boolean isArray()
-
判定此 Class 对象是否表示一个数组类。
-
-
public Class<?> getComponentType()
-
返回表示数组组件类型的 Class。
-
成员变量(Field)获取和设置
-
get(Object o);
-
得到具体对象的该属性的值
-
-
set(Object o, Object value);
-
设置具体对象的该属性的值
-
方法(Method)调用
-
invoke( Object o,Object... args )
-
o是调用该方法的对象 , args是调用该方法时传入的参数
-
内省机制(Introspector)
定义
内省机制其实是通过反射区访问JavaBean对象的属性。
内省的使用
//创建对象 User user=new User(); //创建属性描述器 PropertyDescriptor descriptor = new PropertyDescriptor("name",User.class); //获得写方法 Method writeMethod=descriptor.getWriteMethod(); //调用写方法 writeMethod.invoke(user, "lisi"); System.out.println(user);