深夜房间-有意思的新闻内容 深夜房间-有意思的新闻内容

slim,adobe,抽油烟机排行榜-深夜房间-有意思的新闻内容

什么是反射?

Reflection(反射)是被视为动态言语的要害,反射机制答应程序在执行期借助于 Reflection API 获得任何类的内部信息,并能直接操作恣意方针的内部特点及办法。

怎么了解反射?

简略来讲反射便是将传统的开发办法进行回转,传统的办法是经过类创立方针,反射则是经过方针获取类的内部结构,当然也能够经过其他办法来获取类的内部结构。




经过方针得到类,怎么表明?

咱们知道 Java 是面向方针的编程言语,人间万物都能够笼统成方针,反射也不破例,即经过反射机制获取的类的结构也能够笼统成一个方针,怎么来创立这个方针呢?方针一定是经过类来创立的,这个类便是 Class 类,所以咱们说 Class 类是反射的源头,Class 类的每一个实例化方针都表明某个类的结构。

怎么获取 Class 实例化方针?

不能在外部经过结构函数创立 Class 的实例化方针,这是由于 Class 类的结构函数是私有的,如下图所示。




Java 供给了三种办法来实例化 Class:

1、调用 Class 的静态办法 forName(String className) 创立,将方针类的全限制类名(全限制类名便是包含地点包信息的类名全称,如java.lang.String)作为参数传入,即可获取对应的 Class 方针,forName(StringclassName) 办法的界说如下图所示。




2、经过方针类的 class 创立,Java 中的每一个类都能够调用类.class,这儿的 class 不是特点,它叫作“类字面量”,其作用是获取内存中方针类型 class 方针的引证。

3、经过方针类实例化方针的 getClass() 办法创立。getClass() 办法界说在 Object 类中,被一切类承继,经过实例方针获取内存中该类 class 方针的引证,getClass() 办法的界说如下图所示。




上述三种实例化 Class 方针的详细操作如下所示。

public class Test {
public static void main(String[] args) {
try {
Class clazz = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
}
Class clazz2 = String.class;
String str = new String("Hello");
Class clazz3 = str.getClass();
}
}


获取类的结构

咱们能够经过 Class 实例化方针获取类的结构,那么类的结构包含哪些内容呢?比方成员变量、成员办法、结构函数、父类、完结的接口等等,都是类的结构,反射也供给了相应的 API 来获取这些内容。

Class 用来描绘方针类的结构,叫做方针类的运转时类,常用办法如下。

public Class
public Class
public Constructor[] getConstructors():回来运转时类的public结构办法。
public Constructor[] getDeclaredConstructors():回来运转时类的悉数结构办法。
public Method[] getMethods():回来运转时类的public办法。
public Method[] getDeclaredMethods(): 回来运转时类的悉数办法。
public Field[] getFields() :回来运转时类的public成员变量。
public Field[] getDeclaredFields() :回来运转时类的悉数成员变量。


Method 用来描绘运转时类的办法,常用办法如下。

public Class
public Class
public int getModifiers() : 回来办法的拜访权限修饰符。
public String getName(); : 回来办法名。
public Class


Field 用来描绘运转时类的成员变量,常用办法如下。

public int getModifiers() : 回来成员变量的拜访权限修饰符。
public Class
public String getName() : 回来成员变量的称号。


Constructor 用来描绘运转时类的结构办法,常用办法如下。

public int getModifiers() : 回来结构办法的拜访权限修饰符。
public String getName() : 回来结构办法名。
public Class


反射的运用

1、经过反射调用成员办法,反射便是将惯例办法进行回转,首要创立实例化方针,然后该方针的办法也笼统成方针,咱们称之为办法方针。调用办法方针的 invoke 办法来完结事务需求,并将实例化方针作为参数传入 invoke 办法中。整个进程操作的是办法方针,与惯例办法恰好相反,如下所示。

public class Student{
public static void main(String[] args) {
Student student = new Student();
student.setId(1);
student.setName("张三");
Class clazz = student.getClass();
try {
//获取showInfo()办法
Method method = clazz.getDeclaredMethod("showInfo", null);
//经过invoke办法完结调用
method.invoke(student, null);
} catch (NoSuchMethodException e) {
}
}
}


2、经过反射机制,咱们也能够在程序运转期间拜访成员变量,并获取成员变量的相关信息,如称号、数据类型、拜访权限等,详细操作如下所示。

public class Student{
private int id;
public String name;
}
public class Test {
public static void main(String[] args) {
Class clazz = Student.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
int modifiers = field.getModifiers();
Class typeClass = field.getType();
String name = field.getName();
System.out.println("成员变量"+name+"的数据类型是:"+typeClass.getName()+",拜访权限是:"+getModifiers(modifiers));
}
}
public static String getModifiers(int modifiers) {
String result = null;
switch (modifiers) {
case 0:
result = "";
break;
case 1:
result = "public";
break;
case 2:
result = "private";
break;
case 4:
result = "protected";
break;
}
return result;
}
}


3、经过反射机制修正成员变量的值,咱们知道 private 成员变量在外部是无法拜访的,所以直接经过反射来修正 private 成员变量会抛出反常,怎么处理呢?经过反射的“暴力修正”即可,所谓的“暴力修正”是指修正 private 成员变量的拜访权限,设置为 ture 时,表明能够修正,false 表明不能修正,会抛出反常,默认值为false 。可经过调用 setAccessible(booleanflag) 办法完结权限设置,详细操作如下所示。

public class Test {
public static void main(String[] args) {
Class clazz = Student.class;
Field[] fields = clazz.getDeclaredFields();
Student student = new Student();
for (Field field : fields) {
try {
if(field.getName().equals("id")) {
field.setAccessible(true);
field.set(student, 1);
}
if(field.getName().equals("name")) {
field.set(student, "张三");
}
} catch (IllegalArgumentException e) {
}
}
System.out.println("学生信息");
System.out.println("ID:"+student.getId());
System.out.println("名字:"+student.name);
}
}


4、经过反射机制调用结构函数来创立方针,这种操作在一些东西类或许结构中运用十分广泛,经过配置文件来创立实例化方针便是经过这种办法来完结的,详细操作如下所示。

public class Student{
private int id;
public String name;
public Student() {
}
public Student(int id,String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
public class Test {
public static void main(String[] args) {
Class clazz = Student.class;
try {
//获取Student无参结构函数
Constructor constructor = clazz.getConstructor(null);
Student student = constructor.newInstance(null);
System.out.println(student);
//获取Student有参结构函数
Constructor constructor2 = clazz.getConstructor(int.class,String.class);
Student student2 = constructor2.newInstance(1,"张三");
System.out.println(student2);
} catch (NoSuchMethodException e) {
}
}
}


动态署理

动态署理是反射十分重要的一个实践运用,是指在编译期并没有确认详细的署理类,在程序运转期间依据Java代码的指示动态地生成的办法,那么这个动态生成的功用是谁来完结的呢?

java.lang.reflect 包中供给了 InvocationHandler 接口,经过该接口能够在程序运转期间动态生成署理类。首要,自界说一个类MyInvocationHandler,完结 InvocationHandler 接口,这个类便是动态署理类的模版,如下所示。

public class MyInvocationHandler implements InvocationHandler {
private Object obj = null;
public Object bind(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(MyInvocationHandler.class.getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object result = method.invoke(obj, args);
return result;
}
}


在 invoke 办法中能够增加非事务代码,然后做到事务代码和非事务代码的别离,动态署理的详细运用如下所示。

public interface Phone {
public String salePhone();
}
public class Apple implements Phone{
@Override
public String salePhone() {
// TODO Auto-generated method stub
return "出售iPhone手机";
}
}
public interface Car {
public String saleCar();
}
public class BMW implements Car{
@Override
public String saleCar() {
// TODO Auto-generated method stub
return "出售宝马轿车";
}
}
public class Test {
public static void main(String[] args) {
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
Phone phone = (Phone)myInvocationHandler.bind(new Apple());
System.out.println(phone.salePhone());
Car car = (Car)myInvocationHandler.bind(new BMW());
System.out.println(car.saleCar());
}
} 有协助请点赞哦!感谢
作者:admin 分类:最近大事件 浏览:305 评论:0