java的反射可以绕过访问权限,访问到类的非公有方法和成员,利用反射还可以访问内部类、匿名内部类的私有属性。可能这点会引起安全性的讨论。反射的使用帮助解决很多复杂的问题,其运行时的类型检查,动态调用,代理的实现等,反射为我们写程序带来了很大的灵活性,很多功能都是基于反射。
一、实体类
package cn.moving.reflect;
import java.io.InputStream;
import java.util.List;
public class Person {
private String name = "maomao";
private int password;
private static int age = 23;
private static final Person instance = new Person();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
public static int getAge() {
return age;
}
public static void setAge(int age) {
Person.age = age;
}
private Person() {
System.out.println("person");
}
public static Person getInstance() {
return Person.instance;
}
public Person(String name) {
this.name = name;
System.out.println("person name");
}
public Person(String name, int age) {
System.out.println("姓名:" + name + "年龄:" + age);
}
public Person(int age) {
System.out.println("age");
}
public Person(List list) {
System.out.println("list");
}
public void play(String name, int age) {
System.out.println("姓名:" + name + "年龄:" + age + "正在玩");
}
public Class[] aa(String name, int[] password) {
return new Class[] { String.class };
}
private void bb(InputStream is) {
System.out.println(is);
}
public static void cc(int num) {
System.out.println(num);
}
public static void main(String args[]) {
for (String s : args) {
System.out.println(s);
}
}
}
二、反射字段
package cn.moving.reflect;
import java.lang.reflect.Field;
import org.junit.Test;
public class ReflectField {
/**
* 反射类的字段
* @throws Exception
* @throws SecurityException
*/
// 解剖(=反射)private String name = "maomao";
// 私有字段
@Test
public void reflectName() throws SecurityException, Exception {
Class clazz = Class.forName("cn.moving.reflect.Person");
Field f = clazz.getDeclaredField("name");
f.setAccessible(true);
Person p = new Person("haha");
Object value = f.get(p);
Class type = f.getType();
System.out.println(type);
if (type.equals(String.class)) {
String name_value = (String) value;
System.out.println(name_value);
}
f.set(p, "LanWenTao");
System.out.println(f.get(p));
}
@Test
// private static int age = 23;静态私有的属性
public void reflectAge() throws Exception {
Class clazz = Class.forName("cn.moving.reflect.Person");
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
System.out.println(f.get(null));;
}
}
三、反射构造方法
package cn.moving.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.junit.Test;
public class ReflectConstructor {
/**
* 反射构造方法
*
* @throws ClassNotFoundException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
*/
@Test
public void reflectNoArgumentConstrustor() throws Exception {
Class clazz = Class.forName("cn.moving.reflect.Person");
Constructor[] cons = clazz.getDeclaredConstructors();
Constructor c = null;
for (Constructor con : cons) {
con.setAccessible(true);
c = con;
}
Person p = (Person) c.newInstance(null);
System.out.println(p.getName());
}
@Test
public void reflectConstructor() throws Exception {
Class clazz = Class.forName("cn.moving.reflect.Person");
Constructor c = clazz.getConstructor(String.class, int.class);
Person p = (Person) c.newInstance("XiaoMing", 22);
System.out.println(p.getName());// ???????????
}
}
四、反射普通方法
package cn.moving.reflect;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
public class reflectMethod {
/**
* 反射普通方法
*/
// public void play(String name, int age)
@Test
public void reflectPlay() throws Exception {
Class clazz = Class.forName("cn.moving.reflect.Person");
Method method = clazz.getMethod("play", String.class, int.class);
Person p = new Person("ZhangSan",22);
method.invoke(p, "sdfdsf",44);
}
//public Class[] aa(String name, int[] password)
@Test
public void reflectClass() throws Exception{
Class clazz = Class.forName("cn.moving.reflect.Person");
Method method = clazz.getMethod("aa", String.class,int[].class);
Person p = Person.getInstance();
Class[] cs =(Class[]) method.invoke(p, "ZhangSan",new int[]{12,332,4,23,4});
System.out.println(cs[0]);
System.out.println(p.getName());
}
@Test
//private void bb(InputStream is)
public void reflectbb() throws Exception{
Class clazz = Class.forName("cn.moving.reflect.Person");
Method method = clazz.getDeclaredMethod("bb", InputStream.class);
method.setAccessible(true);
Person p = Person.getInstance();
method.invoke(p, new FileInputStream("c:\\1.txt"));
}
@Test
//public static void cc(int num)
public void reflectcc() throws Exception{
Class clazz = Class.forName("cn.moving.reflect.Person");
Method method = clazz.getMethod("cc",int.class);
method.invoke(null,34535);//静态不传对象也可以
}
@Test
//public static void main(String agrs[])
public void reflectMain()throws Exception{
Class clazz = Class.forName("cn.moving.reflect.Person");
Method method = clazz.getMethod("main", String[].class);
// method.invoke(null,new String[]{"sdfds","sdfsd"}); //wrong
// method.invoke(null,(Object)new String[]{"sd2342ds","sdfsd"});//ok
method.invoke(null,new Object[]{new String[]{"sd2342ds","sdfsd"}});//true
}
}
注:main方法的参数是一个字符串数组,即publicstaticvoidmain(String[]args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,newString[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
分享到:
相关推荐
在向学生讲解Class.forName()方法的使用时,有时需要扩展讲解为什么这样书写的原理,于是,扩展讲解Java反射技术可以查看被监视类的方法(构造方法和普通方法)、公有属性的功能,以达到封闭功能的效果。该例子使用...
详细讲解了java反射技术,简单易懂,可以很轻松的学习java的反射机制
java反射技术应用的很广泛,多看源码,对理解java反射的理解会有很好的认识,这个源码有我自己的理解在里边
Java反射技术指的是在运行时动态地获取类的信息、调用对象的方法、操作类的属性等能力。通过反射,程序可以在运行时检查类、实例化对象、调用方法、获取和设置属性,甚至可以动态修改类的结构。 Java反射技术的核心...
java 反射技术
对初学者而言这是一个不错的对jdbc学习的资源。
运行程序,指定一个要分析的类名称,如java.lang.Double,输出类中声明的属性、方法、构造函数等。
Java反射技术浅谈
在向学生讲解Class.forName()方法的使用时,有时需要扩展讲解为什么这样书写的原理,于是,扩展讲解Java反射技术可以查看被监视类的方法(构造方法和普通方法)、公有属性的功能,以达到封闭功能的效果。该例子使用...
利用java反射技术实现动态搜索所有字段
主要介绍了Java反射技术原理与用法,结合实例形式分析了Java反射技术的基本概念、功能、原理、用法及操作注意事项,需要的朋友可以参考下
Java反射技术浅谈 (1)
java反射技术,java设计模式,spring security安全管理手册,说明,使用
自己写的一些关于java使用反射的一些例子,感觉里面应该写的挺全了。希望有助于大家的学习.
利用Java反射、IO、图形化技术相结合实现的一个类搜索小工具,可以直观的看到效果,代码不多,注释齐全,适合初阶段学习。
使用 Java 反射封装 JavaBean <br> 说明:这个程序在没有使用Hiberante时挺有用的 需要一个数据库查询语句 对应的JavaBean的全名(现在是Class,原来Class.getName()) 返回List包含多个JavaBean
Java反射机制主要提供了以下功能: l 在运行时判断任意一个对象所属的类; l 在运行时构造任意一个类的对象; l 在运行时判断任意一个类所具有的成员变量和方法; l 在运行时调用任意一个对象的方法; l 生成...
反射本身是JAVA 语言的特性,使JAVA 语言有一种在运行时态自“自观”的能力。而 其他面向对象的语言却没有类似的功能。
主要介绍了基于Java反射技术实现简单IOC容器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Java反射机制的使用和学习方法,从底层阐述Java反射机制的原理,让我们更加了解Java反射