Java_反射机制
Posted zlfxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java_反射机制相关的知识,希望对你有一定的参考价值。
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 stub
X 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 stub
Class<?> 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 stub
Class<?> 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 stub
Class<?> 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 block
e.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;
以上是关于Java_反射机制的主要内容,如果未能解决你的问题,请参考以下文章