现在的位置: 首页 > 综合 > 正文

黑马程序员_java的反射机制

2013年08月28日 ⁄ 综合 ⁄ 共 3505字 ⁄ 字号 评论关闭
黑马程序员_java反射机制
------android培训java培训、期待与您交流!------

什么是反射:反射其实就加载类解剖类的组成部分。
通常在写框架时,就需要使用大量的反射技术来完成一些操作。
在java中如何来使用反射技术?
1.获取此类的字节码对象。可以通过java中最常见的三种方式获取。
(1)Class.forName("类的完整路径");//就是包名加类名
(2)类名.class
(3)对象名.getClass();
2.解剖里面类中的组成部分,分别是(成员变量,成员函数,构造函数)。
同过Class类中的一些方法可以实现,分别是:
getFields()//获取此类的所有public修饰的字段
getMethods();获取此类的所有public修饰的函数
getConstructors();//获取此类所有被public修饰的构造函数
getField(name)//获取此类被public修饰名为name的字段
getMethod(name,Types)//获取此类被public修饰名为name,参数为Types的方法,因为参数可以有多个,所以Types是可变参数类型
getConstructor(Types)//根据Types参数获取此类被public修饰的构造函数,Types是可变参数类型。
----------------------------------------------
getDeclaredFields()//获取此类所有的字段,也包含私有的。
getDeclaredMethods();获取此类的所有的函数,也包含私有的
getDeclaredConstructors();获取此类的所有的构造函数,也包含私有的
getDeclaredField(name)//获取此类中为名name的字段,也包含私有的
getDeclaredMethod(name,Types)//获取此类的名为name,参数为Types的方法,因为参数可以有多个,所以Types是可变参数类型,也包含私有的。

getDeclaredConstructor(Types)//根据Types参数获取此类的构造函数,Types是可变参数类型,也包含私有的。
(1)(通过反射获取字段,并使用)
package Test;
import java.lang.reflect.Field;
class Person{
	public String name;
}
public class Demo1 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("Test.Person");//获得Person类字节码对象
		Person p=new Person();
		Field fieName=clazz.getField("name");
		String str=(String)fieName.get(p);//获取p对象中的name字段的值
	}
}

(2)(通过反射获取成员函数,并调用)

package Test;
import java.lang.reflect.Method;

class Person{
	public void show(){
		System.out.println("我是无参show方法");
	}
	public void show(String name){
		System.out.println("我是有参"+name);
	}
}
public class Demo1 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("Test.Person");//获得Person类字节码对象
		Person p=new Person();
		Method metShow=clazz.getMethod("show",null);//获取无参show方法,没参所以传null
		Method metShow2=clazz.getMethod("show",String.class);//获取有参show方法。
		metShow.invoke(p,null);//用p对象调用此方法
		metShow2.invoke(p,"show方法");
	}
}

(3)(通过反射获取构造函数,并创建对象)

package Test;
import java.lang.reflect.Constructor;

class Person{
	public Person(){
		System.out.println("调用无参构造函数创建对象");
	}
	public Person(int age,String name){
		System.out.println("调用有参构造函数创建对象");
	}
}
public class Demo1 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("Test.Person");//获得Person类字节码对象
		Constructor constru1=clazz.getConstructor(null);//获取此类的无参构造函数
		Constructor constru2=clazz.getConstructor(int.class,String.class);//获取此类多参的构造函数
		constru1.newInstance(null);//调用无参构造函数创建对象
		constru2.newInstance(34,"黑马_小爻");//调用多参构造函数创建对象
	}
}

如果是非public修饰的成员如何获取并使用呢?
我就举一个例子,因为其他的都一样
案例(获取非public修饰的成员的函数并调用)
package Test;
import java.lang.reflect.Method;

class Person{
	private void show(){
		System.out.println("我来了,黑马!!");
	}
}
public class Demo1 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("Test.Person");
		Person p=new Person();
		Method method=clazz.getDeclaredMethod("show",null);//由show方法时private的,所以只能通过getDeclaredMethod方法才能获得
		method.setAccessible(true);//这里为true代表java使用它时不对其进行访问权限语法检查
		method.invoke(p,null);
		
	}
}

有一件事情值得注意,如果方法的参数为数组类型,通过反射获取此方法时一定要记得将数组强转为Object
如:通过反射获取main方法。
package Test;
import java.lang.reflect.Method;

class Person{
	public static void main(String[] args){
		System.out.println("Person");
	}
	public static void show(Object[] obj){
		System.out.println(obj.length);
	}
}
public class Demo1 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("Test.Person");
		Method met=clazz.getMethod("main",String[].class);
		met.invoke(null,(Object)new String[]{"你好黑马"});
		/*为什么要将String数组强转为Object对象呢?
		 * 这是java升级后遗留下来的问题,因为在java1.4版本的时候,还没有可变参数类型时,我们这里参数类型是一个Object[]数组
		 * 我们把Object数组中的每个角标元素来出来当方法参数。来确定我们要获取的方法
		 * 1.5有了可变参数后,java为了使旧版本能够兼容新版本,所以只要你传数组,还是按老办法获取方法
		 * 所以上面的运行实际是把数组拆开后把其中的元素传进去的,并不是把String数组传进去的。
		 * */
	}
}

邮箱:wolaoben7252@qq.com

抱歉!评论已关闭.