Java 反射 例子
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中
它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编
译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如
这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能
的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功
能。
java的反射机制就是增加程序的灵活性,避免将程序写死到代码里,例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。使用反射: class.forName("person").newInstance(); 而且这个类描述可以写到配置文件中,如 **.xml, 这样如果想实例化其他类,只要修改配置文件的"类描述"就可以了,不需要重新修改代码并编译。
在这里先看一下sun为我们提供了那些反射机制中的类:
java.lang.Class;
java.lang.reflect.Constructor; java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
很多反射中的方法,属性等操作我们可以从这四个类中查询。
http://blog.youkuaiyun.com/liujiahan629629/article/details/18013523
首先定义一个bean
JavaBean是符合某种规范的Java组件,也就是Java类。
它必须满足如下规范:
1)必须有一个零参数的默认构造函数
2)必须有get和set方法,类的字段必须通过get和set
方法来访问。
(get方法无参,set方法有参)
public class SimpleBean {
private String name;
private String[] hobby;
public SimpleBean() {}
public SimpleBean(String name, String[] hobby) { this.name = name; this.hobby = hobby; }
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public String[] getHobby() {
return this.hobby;
}
public String toString() {
String returnValue = super.toString() + "\n"; returnValue += "name:=" + this.name + "\n";
if(this.hobby != null) {
returnValue += "hobby:";
for(String s : this.hobby) { returnValue += s + ",";
}
returnValue += "\n";
}
return returnValue;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Exception {
Class clazz = SimpleBean.class;
//使用无参构造函数实例化bean
SimpleBean sb = (SimpleBean)clazz.newInstance();
System.out.println(sb);
//使用有参构造函数实例化bean
Constructor constructor = clazz.getConstructor(new Class[]{String.class, String[].class}); sb = (SimpleBean)constructor.newInstance(new Object[]{"royzhou",new String[]{"football","basketball"}});
System.out.println(sb);
//为name字段设置值
Field field = clazz.getDeclaredField("name"); field.setAccessible(true); //避免private不可访问抛出异常field.set(sb, "royzhou1985"); System.out.println("modify name using Field:=" + sb.getName() + "\n");
//列出类SimpleBean的所有方法
Method[] methods = clazz.getDeclaredMethods();
System.out.println("get methods of class SimpleBean:");
for(Method method : methods) {
if("setHobby".equals(method.getName())) {
//动态调用类的方法来为hobby设置值
method.invoke(sb, new Object[]{new String[]{"tennis","fishing"}});
}
System.out.println(method.getName());
}
System.out.println("\nset by invoke Method");
System.out.println(sb);
}
}
结果显示
SimpleBean@70d76d51
name:=null
SimpleBean@4f4a1ab7
name:=royzhou
hobby:football,basketball,
get methods of class SimpleBean:
toString
setName
getName
setHobby
getHobby
set by invoke Method
SimpleBean@4f4a1ab7
name:=royzhou
hobby:tennis,fishing,
其实在SimpleBean中,只要先定义了
private String name;
private String[] hobby;
然后再右键选择Source-Generate getter and stters 就会自动生成类似
public String getName() {
return this.name;
}
的一段代码。
这里说一下,可能对于一个对象在创建完成后会自动调用 toSting 函数,默认的toSting 函数并没有做啥。
现在重载了toSting 函数,所以一开始就可以多一行
name:=null