Java_反射机制

来源:互联网 发布:js button 文字 编辑:程序博客网 时间:2024/06/11 07:58

1、获取反射的三种方式。

(1)通过类.class.

(2)通过对象.getClass();

(3)通过Class.forName();

最常用,最灵活的当属Class.forName();

2、反射是将类的各种成分映射成相应的类。

实例:

package com.lixinghua.fanshe;public class X{}
package com.lixinghua.fanshe;public class GetClassDemo01{/** * @param args */public static void main(String[] args){// TODO Auto-generated method stubX x = new X();System.out.println(x.getClass().getName());}}
通过上面的代码可以获取X类的完整的包名,但是x.getClass()这个方法哪里来的呢?

任何一个类如果没有明确声明继承自哪个类,则默认继承Object类。Object类中定义了:public final Class getClass();

3、通过反射的三种方式实例化对象。

Class<?> c1 = null;Class<?> c2 = null;Class<?> c3 = null;//方式一c1 = Class.forName(com.lixinghua.fanshe);//方式二c2 = new X().getClass();//方式三c3 = X.class;System.out.println(c1.getName());System.out.println(c2.getName());System.out.println(c3.getName());
这样最终都可以输出对象X所在的完整的包的名称。

4、反射机制的深入应用。

(1)通过反射调用类中的无参方法

package com.lixinghua.fanshe;import java.lang.reflect.Method;public class GetClassDemo01{/** * @param args */public static void main(String[] args){// TODO Auto-generated method stubClass<?> c1 = null;try{//实例化Class对象c1 = Class.forName("com.lixinghua.fanshe.Person");//Person中的sayHello方法没有参数,所以不需要传递参数Method method = c1.getMethod("sayHello");//调用此方法,必须传递对象实例method.invoke(c1.newInstance());} catch (Exception e){// TODO: handle exception}}}class Person{private String name;public String getName(){return name;}public void setName(String name){this.name = name;}public int getAge(){return age;}public void setAge(int age){this.age = age;}private int age;public Person(){// TODO Auto-generated constructor stub}public void sayHello(){System.out.println("Hello World!");}public String say(String name,int age){return name+"_"+age;}}
(2)通过反射调用类中的有参方法。

public static void main(String[] args){// TODO Auto-generated method stubClass<?> c1 = null;try{//实例化Class对象c1 = Class.forName("com.lixinghua.fanshe.Person");//Person中的say方法中有两个参数Method method = c1.getMethod("say",String.class,int.class);//调用此方法,必须传递对象实例和参数String result = (String)method.invoke(c1.newInstance(),"zlf",22);System.out.println(result);} catch (Exception e){// TODO: handle exception}}
(3)通过反射调用setter以及getter方法。
public class GetClassDemo01{public static void main(String[] args){// TODO Auto-generated method stubClass<?> c1 = null;Object object = null;try{//实例化Class对象c1 = Class.forName("com.lixinghua.fanshe.Person");object = c1.newInstance();} catch (Exception e){// TODO: handle exception}setter(object, "name", "zlf", String.class);setter(object, "age", 22, int.class);System.out.print("姓名:");getter(object, "name");System.out.print("年龄:");getter(object, "age");}public static void setter(Object obj, String att, Object value, Class<?> type){try{Method method = obj.getClass().getMethod("set"+initStr(att), type);//设置方法参数类型method.invoke(obj, value);//调用方法} catch (Exception e){// TODO: handle exception}}public static void getter(Object obj, String att){try{Method method = obj.getClass().getMethod("get"+initStr(att));System.out.println(method.invoke(obj));} catch (Exception e){// TODO: handle exception}}public static String initStr(String old){String string = old.substring(0,1).toUpperCase()+old.substring(1);//单词首字母大写return string;}}

5、将反射应用在工厂模式上。

(1)工厂模式在实际的开发中使用得非常多,通过反射机制改善工厂类,让其在增加子类时可以不用做任何的修改,就可以达到功能的扩充。

package com.lixinghua.fanshe;interface Fruit{public void eat();}class Apple implements Fruit{public void eat(){System.out.println("**吃苹果");}}class Orange implements Fruit{public void eat(){System.out.println("**吃橘子");}}class Factory{public static Fruit getInstance(String className){Fruit fruit = null;try{fruit = (Fruit) Class.forName(className).newInstance();} catch (Exception e){// TODO Auto-generated catch blocke.printStackTrace();}return fruit;}}
(2)接下来该编写主类了。
package com.lixinghua.fanshe;import java.util.Properties;public class Main{public static void main(String[] args){//方法一//Fruit fruit = Factory.getInstance("com.lixinghua.fanshe.Apple");//方法二Properties properties = Init.getProperties();//初始化属性类Fruit fruit = Factory.getInstance(properties.getProperty("apple"));if(fruit!=null){fruit.eat();}}}
(3)主类中通过方法一的话,用户需要知道该类的完整包名,而用户是不可能知道一个借口中有多少个可以使用的子类。所以开发中,最好使用第二种方法,配置属性文件的方法。

属性文件类:

package com.lixinghua.fanshe;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.Properties;public class Init{public static Properties getProperties(){Properties properties = new Properties();File file = new File("fruit.properties");try{if(file.exists())//如果属性文件已经存在{properties.load(new FileInputStream(file));//读取内容}else {//否则新建一个属性文件properties.setProperty("apple", "com.lixinghua.fanshe.Apple");properties.setProperty("orange", "com.lixinghua.fanshe.Orange");properties.store(new FileOutputStream(file), "Fruit Class");}} catch (Exception e){// TODO: handle exception}return properties;}}

原创粉丝点击