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_反射机制的主要内容,如果未能解决你的问题,请参考以下文章

java反射机制

java 中反射机制和内省机制的区别是啥?

#yyds干货盘点# Java 基础 - 反射机制详解

Java反射机制深入详解

Java反射

Java_反射机制