1.什么是反射?
反射就是动态加载对象,并对对象进行剖析。在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能成为Java反射机制。
2.Java反射机制的做用
1). 在运行时判断任意一个对象所属的类
2). 在运行时构造任意一个类的对象
3). 在运行时判断任意一个类所具备的成员变量和方法
4). 在运行时调用任意一个对象的方法
3.java反射机制提供了什么功能?
1). 在运行时可以判断任意一个对象所属的类
2). 在运行时构造任意一个类的对象
3). 在运行时判断任意一个类所具备的成员变量和方法
4). 在运行时调用任一对象的方法
5). 在运行时建立新类对象
4.哪里用到反射机制?
各类框架用的最多的就是反射
加载驱动
读取配置文件
5.运用反射的优缺点
优势:
反射提升了程序的灵活性和扩展性,下降耦合性,提升自适应能力。它容许程序建立和控制任何类的对象,无需提早硬编码目标类
缺点:
(1)性能问题:使用反射基本上是一种解释操做,用于字段和方法接入时要远慢于直接代码。所以反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
(2)使用反射会模糊程序内内部逻辑:程序员但愿在源代码中看到程序的逻辑,反射等绕过了源代码的技术,于是会带来维护问题。反射代码比相应的直接代码更复杂。
6.如何使用java的反射?
a. 经过一个全限类名建立一个对象
1)、Class.forName(“全限类名”); 例如:com.mysql.jdbc.Driver Driver类已经被加载到 jvm中,而且完成了类的初始化工做就好了
2)、类名.class; 获取Class<?> clz 对象
3)、对象.getClass();
b. 获取构造器对象,经过构造器new出一个对象
1). Class.getConstructor([String.class]);
2). Con.newInstance([参数]);
c. 经过class对象建立一个实例对象(就至关与new类名()无参构造器)
1). Class.newInstance();
d. 经过class对象得到一个属性对象
1)、Field c=clz.getFields():得到某个类的全部的公共(public)的字段,包括父类中的字段。
2)、Field c=clz.getDeclaredFields():得到某个类的全部声明的字段,即包括public、private和proteced,可是不包括父类的申明字段 e.
e、经过class对象得到一个方法对象
1). Class.getMethod(“方法名”,class……parameaType);(只能获取公共的)
2). Class.getDeclareMethod(“方法名”);(获取任意修饰的方法,不能执行私有)
3) M.setAccessible(true);(让私有的方法能够执行)
f. 让方法执行
1). Method.invoke(obj实例对象,obj可变参数);-----(有返回值的)
7.反射重要借助哪四个类?
1)、Class:类的对象;
2)、Constructor:类的构造方法
3)、Field:类中的属性对象
4)、Method:类中的方法对象
8.得到一个类的类对象有哪些方式?
方法1:类型.class,例如:String.class
方法2:对象.getClass(),例如:"hello".getClass()
方法3:Class.forName(),例如:Class.forName("java.lang.String")
9.如何经过反射建立对象?
方法1:经过类对象调用newInstance()方法,例如:String.class.newInstance()
方法2:经过类对象的getConstructor()或getDeclaredConstructor()方法得到构造器(Constructor)对象并调用其newInstance()方法建立对象,例如:String.class.getConstructor(String.class).newInstance("Hello");
10.如何经过反射获取和设置对象私有字段的值?
能够经过类对象的getDeclaredField()方法字段(Field)对象,而后再经过字段对象的setAccessible(true)将其设置为能够访问,接下来就能够经过get/set方法来获取/设置字段的值了。
11.如何经过反射调用对象的方法?
import java.lang.reflect.Method;
class MethodInvokeTest {
public static void main(String[] args) throws Exception {
String str = "hello";
Method m = str.getClass().getMethod("toUpperCase");
System.out.println(m.invoke(str)); // HELLO
}
}
12.反射中,Class.forName 和 ClassLoader 区别。
Class.forName(className)方法,其实调用的方法是Class.forName(className,true,classloader);注意看第2个boolean参数,它表示的意思,在loadClass后必须初始化。比较下咱们前面准备jvm加载类的知识,咱们能够清晰的看到在执行过此方法后,目标对象的 static块代码已经被执行,static参数也已经被初始化。
再看ClassLoader.loadClass(className)方法,其实他调用的方法是ClassLoader.loadClass(className,false);仍是注意看第2个 boolean参数,该参数表示目标对象被装载后不进行连接,这就意味这不会去执行该类静态块中间的内容
13.如何获取类的class对象
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。
获取类的Class对象有多种方式:
调用getClass
Boolean var1 = true;
Class<?> classType2 = var1.getClass();
System.out.println(classType2);
输出:class java.lang.Boolean
运用.class 语法
Class<?> classType4 = Boolean.class;
System.out.println(classType4);
输出:class java.lang.Boolean
运用static method Class.forName()
Class<?> classType5 = Class.forName("java.lang.Boolean");
System.out.println(classType5);
输出:class java.lang.Boolean
运用primitive wrapper classes的TYPE 语法
这里返回的是原生类型,和Boolean.class返回的不一样
Class<?> classType3 = Boolean.TYPE;
System.out.println(classType3); 输出:boolean
14.如何获取类的fields
能够经过反射机制获得某个类的某个属性,而后改变对应于这个类的某个实例的该属性值。JAVA 的Class<T>类提供了几个方法获取类的属性。
public FieldgetField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段
public Field[]
getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的全部可访问公共字段
public FieldgetDeclaredField(Stringname)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段
public Field[]
getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的全部字段
15.如何获取类的constructor
经过反射机制获得某个类的构造器,而后调用该构造器建立该类的一个实例
,Class<T>类提供了几个方法获取类的构造器。
public Constructor<T>
getConstructor(Class<?>...
parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
public Constructor<?>[]
getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的全部公共构造方法
public Constructor<T>
getDeclaredConstructor(Class<?>...
parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法
public Constructor<?>[]
getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的全部构造方法。它们是公共、保护、默认(包)访问和私有构造方法