java反射机制及应用分析
2017-07-14 16:59
302 查看
反射是java程序开发语言的特质之一,它允许运行中的java程序获取自身的信息,并且可以操作类或对象的内部属性。
当用户使用一个类的时候,应该先知道这个类,而后通过这个类产生实例化对象,但是“反”指的是通过对象找到类。
通过反射,我们可以在运行时获得程序或者程序中每一个类型的成员和成员的值。
java反射框架主要提供以下功能:
1 在运行时判断任意一个对象所属的类
2在运行时构造任意一个类的对象
3在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)
4在运行时调用任意一个对象的方法
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Person per = new Person(); // 正 着操作
System.out.println(per.getClass().getName()); // 反射
}
}
getClass()方法返回的对象是Class类的对象。
想要取得这个类的实例化对象,有三种方式:
方式1:通过Object的getClass()方法取得,基本不用;
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Person per = new Person(); // 正 着操作
Class <?> cls = per.getClass(); //取得class对象
Systen.out.println(cls.getName());//反射
}
}
方式2:使用“类.class”取得
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Class <?> cls = Person.class; //取得class对象
Systen.out.println(cls.getName());//反射
}
}
方式3:使用Class类内部定义的一个static方法,使用频繁
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Class <?> cls = Class.fornName(“sai.xuexi.fanshe.peroson”); //取得class对象
Systen.out.println(cls.getName());//反射
}
}
新的问题: 取得clas类对象有什么用处呢?
对于对象的实例化操作之前一直依靠构造方法和关键字new完成,在有了class类对象之后,有有了一种提供对象的实例化方法。
例子:通过反射实例化对象
class Person{
public String toString(){
return "Person Class Instance."
}
}
public class TestDemo{
public static void main(String [] args) throwsException{
Person per = new Person(); // 正 着操作
Class <?> cls = Class.fornName(“sai.xuexi.fanshe.peroson”); //取得class对象
Object obj = cls.newInstance();//实例化对象,和使用关键字new一样
Person per = (person)obj;// 向下转型
Systen.out.println(per));//
}
}
使用反射实例化对象 可以减少耦合。(new是造成耦合的关键元凶)
反射在工厂方法中的使用:
反射的深入应用:
以上只是利用Class类作为了反射实例化对象的基本应用,但是对于一个实例化对象而言,它需要调用类之中的构造方法,普通方法,属性。
1 调用构造方法:
调用构造方法有2种
方法1 取得一个类的全部构造方法:
方法2 取得一个类指定参数的构造方法:
方法1的应用:
方法2的应用
2 调用普通方法
3调用成员
类之中最后一个组成部分就是成员(Field,也就是属性)
顶184
当用户使用一个类的时候,应该先知道这个类,而后通过这个类产生实例化对象,但是“反”指的是通过对象找到类。
通过反射,我们可以在运行时获得程序或者程序中每一个类型的成员和成员的值。
java反射框架主要提供以下功能:
1 在运行时判断任意一个对象所属的类
2在运行时构造任意一个类的对象
3在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)
4在运行时调用任意一个对象的方法
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Person per = new Person(); // 正 着操作
System.out.println(per.getClass().getName()); // 反射
}
}
getClass()方法返回的对象是Class类的对象。
想要取得这个类的实例化对象,有三种方式:
方式1:通过Object的getClass()方法取得,基本不用;
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Person per = new Person(); // 正 着操作
Class <?> cls = per.getClass(); //取得class对象
Systen.out.println(cls.getName());//反射
}
}
方式2:使用“类.class”取得
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Class <?> cls = Person.class; //取得class对象
Systen.out.println(cls.getName());//反射
}
}
方式3:使用Class类内部定义的一个static方法,使用频繁
class Person{}
public class TestDemo{
public static void main(String [] args) throwsException{
Class <?> cls = Class.fornName(“sai.xuexi.fanshe.peroson”); //取得class对象
Systen.out.println(cls.getName());//反射
}
}
新的问题: 取得clas类对象有什么用处呢?
对于对象的实例化操作之前一直依靠构造方法和关键字new完成,在有了class类对象之后,有有了一种提供对象的实例化方法。
例子:通过反射实例化对象
class Person{
public String toString(){
return "Person Class Instance."
}
}
public class TestDemo{
public static void main(String [] args) throwsException{
Person per = new Person(); // 正 着操作
Class <?> cls = Class.fornName(“sai.xuexi.fanshe.peroson”); //取得class对象
Object obj = cls.newInstance();//实例化对象,和使用关键字new一样
Person per = (person)obj;// 向下转型
Systen.out.println(per));//
}
}
使用反射实例化对象 可以减少耦合。(new是造成耦合的关键元凶)
反射在工厂方法中的使用:
interface Fruit{ public void eat(); } class Apple implements Fruit{ public void eat(){ System.out.print("chipingguo"); } }; class Orange implements Fruit{ public void eat(){ System.out.print("chijuzi"); } }; class Factory{ public static Fruit getInstance(String className){ Fruit f = null; if("apple".equals(className)){ f = new Apple(); } if ("orange".equals(className)){ f = new Orange(); } return f; } } public class Demo{ public static void mani (String args[]){ Fruit f = null; f =Factory.getInstance("apple"); f.eat(); } }
反射的深入应用:
以上只是利用Class类作为了反射实例化对象的基本应用,但是对于一个实例化对象而言,它需要调用类之中的构造方法,普通方法,属性。
1 调用构造方法:
调用构造方法有2种
方法1 取得一个类的全部构造方法:
public Constructor<?>[] getConstructor() throws SecurityException
方法2 取得一个类指定参数的构造方法:
public Constructor<T>[] getConstructor(Class<?> parameterTypes) throws SecurityException,NoSuchMethodException
方法1的应用:
class Person { public Person() {} public Person(String name) {} public Person(String name,int age) {} } public class TestDemo { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象 Constructor<?> cons [] = cls.getConstructors() ; // 取得全部构造 for(int x = 0; x < cons.length; x++) { System.out.println(cons[x]); } } }
方法2的应用
class Person { private String name; private int age; public Person(String name,int age) { this.name= name ; this.age= age ; } @Override public String toString() { return"Person [name="+ name+ ", age="+ age+ "]"; } } public class TestDemo { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象 // 取得指定参数类型的构造方法 Constructor<?> cons = cls.getConstructor(String.class,int.class) ; Object obj = cons.newInstance("张三", 20); // 为构造方法传递参数 System.out.println(obj); } }
2 调用普通方法
public Method [] getMethods() throws SecurityException; // 取得全部方法 // 取得指定方法 public Method getMethod(String name ,class<?> parameterTypes) throws SecurityException,NoSuchMethodException;
//取得一个类里面的全部方法 class Person { private String name; public void setName(String name) { this.name= name; } public String getName() { return name; } } public class Ceshi{ public static void main(String args[])throws Exception{ Class<?> cls = Class.forName("sai.xuexi.person"); Method md [] =cls .getMethods(); for (int x =0; x<md.length; x++){ System.out.print(md[x]); } } }
//取得一个类里面的特定方法 class Person { private String name; public void setName(String name) { this.name= name; } public String getName() { return name; } } public class Ceshi{ public static void main(String args[])throws Exception{ Class<?> cls = Class.forName("sai.xuexi.person");//取得class对象 Object obj = cls.newInstance(); //实例化对象,没有像person转型 String attribute ="name" //要调用类之中的属性 Method setMd = cls.getMethod("set" + initcap(attribute),String.class);//set name Method getMd =cls.getMethod("get"+ initcap(attribute)); //get Name setMd.invoke(obj,"zhangsan");//等价于 person对象.setName("zhansan") System.out.print(getMd.invoke(obj)); //等价于 person对象.getName } public static String initcap(String str){ return str.substring(0,1).toUpperCase().concat(str.substring(1)); } }
3调用成员
类之中最后一个组成部分就是成员(Field,也就是属性)
//取得本类的全部成员: public Field[] getDeclaredFields() throws SecurityException; //应用 class Person { private String name; } public class Ceshi { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象 Field field [] = cls.getDeclaredFields() ; // 取得全部属性 for(int x = 0; x < field.length; x++) { System.out.println(field[x]); } } } // 取得指定的成员: public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException; //应用 class Person { private String name; } public class Sai { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象 Object obj = cls.newInstance(); // 对象实例化属性才会分配空间 Field nameField = cls.getDeclaredField("name") ; // 找到name属性 nameField.setAccessible(true) ; // 解除封装了 nameField.set(obj, "张三") ; // Person对象.name = "张三" System.out.println(nameField.get(obj)); // Person对象.name
顶184
相关文章推荐
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- 近期活动盘点:基于雷达图像预测未来降水参赛经验分享、大数据基础设施讲座、药品行业分析及大数据应用思享会(11.22-11.29)
- 动态库专题-深入分析Windows和Linux动态库应用异同
- Web API应用架构设计分析(1)
- R语言实用案例分析-相关系数的应用
- 分析:低成本应用先锋 Linux系统大盘点
- Struts在J2EE Web应用服务上的构架分析与案例设计
- Android应用AsyncTask处理机制详解及源码分析
- 统计分析与数据挖掘所涉及的应用领域探讨
- 平台化软件的设计与应用前景分析
- Javascript 拖拽的一些高级的应用——逐行分析代码,让你轻松了解拖拽的原理
- Ketstone TI多内核处理器Navigator Runtime 应用案例分析
- Struts2应用分析
- 人工智能研究分析、方法、范畴及应用
- iOS应用的crash日志的分析基础
- IOS 应用事件的传递分析
- Android开发学习总结(五)——Android应用目录结构分析
- 当前流行的J2EE WEB应用架构分析(转)
- Android学习笔记之实现一个文档查看器(一)——应用分析