我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!
注意:反射破坏了java的封装特性
新建一个实体类:
package com.yitian.javabase;
/**
* @author :yitianren
* @date :Created in 2019-5-21 14:22
* @description:
* @modified By:
* @version: $
*/
public class Perple {
private int age;
private String name ;
private final static int iphone=123;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Perple{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public final void say(){
System.out.println("我被调用了!");
}
public final void outNum (int i){
System.out.println("反射调用的数字为:"+i);
}
}
获取Class的三种方式:
//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
// 类型的对象,而我不知道你具体是什么类,用这种方法
Perper p1 = new Perper ();
Class c1 = p1.getClass();
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
// 这说明任何一个类都有一个隐含的静态成员变量 class
Class c2 = Perper .class;
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
// 但可能抛出 ClassNotFoundException 异常
Class c3 = Class.forName("com.yitian.javabase.Perper ");
通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等
查阅 API 可以看到 Class 有很多方法:
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
实例演示:
package com.yitian.javabase;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author :yitianRen
* @date :Created in 2019-5-21 14:17
* @description:
* @modified By:
* @version: $
*/
public class Reflect {
public static void main(String[] args) throws Exception {
Class c1=Perple.class;
Object o=c1.newInstance();//实例化对象
System.out.println("类名:"+c1.getName());
Field[] files=c1.getFields();
for (int i = 0; i < files.length ; i++) {
System.out.println("属性:+"+files[i].getName());
}
Field[] fields1=c1.getDeclaredFields();
for (int i = 0; i < fields1.length ; i++) {
System.out.println("包含私有属性:+"+fields1[i].getName());
}
//获得类的所有方法。
Method[] allMethods = c1.getDeclaredMethods();
for(Method method : allMethods) {//获取特定的方法
//System.out.println(method.getName());//work say
if(method.getName().equals("say")){
method.invoke(o);
System.out.println("say方法");
}
//带参数的方法 反射调用
if(method.getName().equals("outNum")){
method.invoke(o,1);
System.out.println("outNum方法");
}
}
Field f=c1.getDeclaredField("iphone");
f.setAccessible(true);//私有方法可以被调用
System.out.println("获取私有方法iphone:"+f.getName());
//Method me=c1.
}
}
博客介绍了Java反射机制,它允许程序在运行时获取类的内部信息,能让代码更灵活、降低耦合度,但使用不当会消耗大量资源,还会破坏Java封装特性。同时列举了新建实体类、获取Class的三种方式,以及Class类获取成员变量、方法等的多种方法并给出实例演示。
1191

被折叠的 条评论
为什么被折叠?



