缘起
最近在学习Java语言,所以相比较一下Java和Objective-c的反射机制的用法。什么是反射?
简单的说就是程序在运行时能够获取某个特定类的信息。只要给定类的名字,那么就可以通过反射
机制来获得类的所有信息。包括其访问修饰符、父类、实现的接口、属性和方法的所有信息,并可
在运行时创建对象、修改属性(包括私有的)、调用方法等。
Java
Java反射机制主要提供以下功能:
<ol>
<li>在运行时判断任意一个对象所属的类</li>
<li>在运行时构造任意一个类的对象</li>
<li>在运行时获取任意一个类所具有的成员变量和方法</li>
<li>在运行时调用任意一个对象的方法</li>
</ol>
在java.lang.refelect包下
<ol>
<li>Fiele类:代表类的成员变量</li>
<li>Method类:代表类的方法</li>
<li>Constructor类:代表类的构造方法</li>
</ol>
Class 对象是反射的起源,一切从Class对象开始。获取Class对象的方式
获取方式 | 说明 | 示例 |
---|---|---|
Object.getClass() | 获取指定示例的Class | String str = "abc";Class c1 = str.getClass() |
.class | 直接获取当前 | Class listClass = ArrayList.class |
Class.forName() | 传入类的路径 或者全称 | Class c = Class.forName("java.lang.String"); |
Primitive.TYPE | 基本数据类型的包装获取 | Class longClass = Long.TYPE |
例子:
<pre>
class Jober{
private String name;
private int age;
public String getName() {
return name;
}
public Jober() {
System.out.println("heheheh");
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Jober(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return "Jober [name= "+ name +", age= "+age+ "]";
}
}
</pre>
1.要获取上面类的信息
<pre>
//获取类型
import java.lang.reflect.*;
public class Reflection {
public static void main(String[] args) {
try {
//获取Jober对象
Class<?> class1 = Class.forName("com.wanlian.douya.javal.Jober");
Jober jober = new Jober("zhangsna",13);
Class<?> class2 = jober.getClass();
Class<?> class3 = Jober.class;
Class<?> class4 = int.TYPE; //获取基本数据类型
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
</pre>
2.获取方法
<pre>
Class<?> class1 = Class.forName("com.wanlian.douya.javal.Jober");
Method []m = class1.getDeclaredMethods();
for (Method method : m) {
System.out.println(method.toString());
}
//public java.lang.String com.wanlian.douya.javal.Jober.toString()
//public java.lang.String com.wanlian.douya.javal.Jober.getName()
//public void com.wanlian.douya.javal.Jober.setName(java.lang.String)
//public int com.wanlian.douya.javal.Jober.getAge()
//public void com.wanlian.douya.javal.Jober.setAge(int)
</pre>
3.获取属性(成员变量)
<pre>
import java.lang.reflect.*;
public class Reflection {
public static void main(String[] args) {
try {
Class<?> class1 = Class.forName("com.wanlian.douya.javal.Jober");
Field []fields = class1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.toString());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//两个成员变量
//private java.lang.String com.wanlian.douya.javal.Jober.name
//private int com.wanlian.douya.javal.Jober.age
</pre>
4.获取构造方法
<pre>
Constructor<?> []constructors = class1.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.toString());
}
//声明的两个构造方法 一个无参数,一个有参数的
//public com.wanlian.douya.javal.Jober(java.lang.String,int)
//public com.wanlian.douya.javal.Jober()
</pre>
5.获取指定方法并调用
<pre>
//获取Class类
Class<?> class1 = Class.forName("com.wanlian.douya.javal.Jober");
//获取指定的构造方法
Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{});
//创建一个实例对象
Jober jober = (Jober)constructor.newInstance(new Object[]{});
//获取指定的方法
Method method =class1.getDeclaredMethod("setName",new Class[]{String.class});
System.out.println(method.toString());
//调用改方法
method.invoke(jober, new Object[]{"zhangsan"});
System.out.println(jober.getName());
</pre>
网友评论