声明:Java中编译类型有两种
- 静态编译:在编译时确定类型,绑定对象即通过
- 动态编译:运行时确定类型,绑定对象。动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。
一、什么是反射
Java反射是Java被视为动态(或准动态)语言的一个关键性性质。这个机制允许程序在运行时透过Refiection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、superclass(例如Object)、实现之interfaces(例如Cloeable),也包括fields和method的所有信息,并可于运行时改变fields内容或唤起methods。
Refiection可以在运行时加载、探知、适应编译期间完全未知的classes。即Java程序可以加载一个运行时才得知名称的class,获取其完成构造,并生成其对象实体、或对其fields设值、或唤起methods。
反射(reflection)运行静态语言在运行时(runtime)检查、修改程序的结构与行为。
在静态语言汇总,使用一个变量时,必须知道它的类型。在Java中,变量的类型信息在编译时都保存到了class文件中,这样在运行时才能保证准确无误;换句话说,程序在运行时的行为都是固定的。如果想在运行时改变,就需要反射这东西了。
二、反射的特点
1.优点:主要是其动态性
- 1.反射和new 都能创建用户对象,并且调用里面的方法,但是反射是针对字符串编程,new是针对实体类编程
- 2.可以使框架更灵活
- 3.可以深入到类的内部结构,去做一些操作。
2.缺点:主要是性能损失
三、实现Java反射机制的类都位于java.lang.reflect包中:
1、Class类:代表一个类
2、Field类:代表类的方法
3、Method:代表类的方法
4、Constructor类:代表类的构造方法
5、Array类:提供了动态创建数组,以及访问数组的元素的静态方法
四、使用场景
反射主要在构件框架时用的多
举例:
1.根据配置文件来动态生成相对的类型对象
2.根据注解来动态确定程序执行逻辑,如retrofit
3.生成动态代理
4.突破一些sdk的API接口限制(访问一个类的私有字段,私有方法等)
5.替代方案
反射主要运用在构件框架上,平常项目中运用不到
- 使用注解进行标记
- 用过注解处理器(API)编译时帮我们生成相关代码
特点:
①:没用运行时性能损失,因为性能损失在编译器了;②:还保留了类型信息
六、案例
//案例一
package reflect;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取类的Class对象实例
Class person = Class.forName("reflect.Person");
//根据Class对象实例获取Constructor对象
//Constructor constructor = person.getConstructor();
//使用Class对象的newInstance方法获取反射类对象
Object object = person.newInstance();
//获取setName方法的Method对象,setName方法的参数类型为String
Method setMethod = person.getMethod("setName", String.class);
// setMethod.setAccessible(true);
//将参数值写入Method对象中
Object setInvoke = setMethod.invoke(object, "李四");
//获取Method对象中的getName方法
Method getMethod = person.getMethod("getName");
//获取Method对象中的getName方法的属性值
Object getInvoke = getMethod.invoke(object);
//输出得到的结果
System.out.println(getInvoke);
}
}
class Person implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private char sex;
private int weight;
private int height;
private String bitth;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getBitth() {
return bitth;
}
public void setBitth(String bitth) {
this.bitth = bitth;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", weight=" + weight + ", height=" + height + ", bitth="
+ bitth + "]";
}
}
package reflect;
import java.io.Serializable;
public class ReflectTest2 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class forName = Class.forName("reflect.Person1");
Person1 p=(Person1)forName.newInstance();
p.setName("张三");
String s = p.toString();
System.out.println(s);
}
}
class Person1 implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private char sex;
private int weight;
private int height;
private String bitth;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getBitth() {
return bitth;
}
public void setBitth(String bitth) {
this.bitth = bitth;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", weight=" + weight + ", height=" + height + ", bitth="
+ bitth + "]";
}
}