黑马程序员---java反射及反射中的疑惑


------- android培训java培训、期待与您交流! ----------

1.java反射机制的作用
        使java具备了动态性,可以在运行时构造任意一个类的对象,可以在运行时获取任意类的任意成员,并修改其成员变量或者调用其方法。写程序时(比如框架)无法知道将来要被调用的类名,所以,无法new对象。所以,反射机制解决了框架要解决的核心问题。反射就是把java类中的各个成分映射成相应的java类。比如:成员变量映射到Field类。
2.反射机制的主要成员类
         Class类: 位于java.lang包中,Class类的实例对象是某个类的字节码。
         以下类均位于java.lang.reflect包中:
          Field 类:代表类的成员变量。该类提供一系列方法操作成员变量          Method类:代表类的方法。提供invoke方法,用以调用方法。
         Constructor 类:Constructor 提供关于类的单个构造方法的信息以及对它的访问权限
         Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

         Modifier 类提供了 static 方法和常量,对类和成员访问修饰符进行解码。

3.反射机制中主要的成员类关系图

4.获取Class对象方式

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。

三种获取Class对象的方式:

1.通过Object类的getClass()方法。例如:

Class c1 = new String("").getClass();

2.通过Class类的静态方法——forName()来实现:

Class c2 = Class.forName("java.lang.String");

3.类名.class

Class c3 = String.class;


5.使用反射的综合代码示例:

package com.itheima;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 对于反射的演示。获取类的字节码,并获得其中的成员变量,构造方法以及成员函数。
 * 此处以String类为例。
 * @author wu
 */
public class ReflectTest
{

	/**
	 * @param args
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 */
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
	{
		//获取String的字节码的三种方式
		Class clazz1 = String.class;
		Class clazz2 = Class.forName("java.lang.String");
		Class clazz3 = new String("abc").getClass();
		
		//反射方式获取类中的成员变量
		Field[] fields = clazz1.getDeclaredFields();
		System.out.println("---------成员变量列表---------");
		for (Field field : fields)
		{
			//打印反射获取到的String类中成员变量
			System.out.println(field);
		}
		
		//反射方式获取类中构造方法
		Constructor[]  constructors = clazz2.getDeclaredConstructors();
		System.out.println("---------构造方法列表---------");
		for (Constructor constructor : constructors)
		{
			//打印反射获取到的构造方法。
			System.out.println(constructor);
		}
		
		//反射获取类中成员方法
		Method[] methods = clazz3.getDeclaredMethods();
		System.out.println("---------成员方法列表---------");
		for (Method method : methods)
		{
			//打印通过反射获取的方法列表
			System.out.println(method);
		}
		
		//通过反射方式构建类的实例对象,首先获取构造方法,再通过指定构造方法构建对象
		Constructor constru = clazz1.getConstructor(String.class);
		String str = (String) constru.newInstance("Hello java!");
		System.out.println(str);
		
	}

}
反射技术与泛型结合练习中遇到的问题:

package com.itheima;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

/**
 * 
 * 
 * @author Wu
 */
public class Test1
{

	public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException,
		InvocationTargetException, NoSuchMethodException, SecurityException
	{
		// TODO Auto-generated method stub
		// ------------------打印int[].class中的方法-------------------
		int[] arr = new int[3];
		Class clazz1 = int[].class;
		Method[] methods1 = clazz1.getDeclaredMethods();
		System.out.println("-------int[].class中的方法-------");
		if (methods1.length == 0)
		{
			// System.out.println("int[].class---->没有成员方法");
		}
		Constructor[] constructor = clazz1.getDeclaredConstructors();
		if (constructor.length == 0)
		{
			// System.out.println("int[].class---->没有构造方法");
		}
		// System.out.println(clazz1.getName());
		// 只要参数化泛型类型时,不是String。貌似就可以运行时添加和取出任意类型。
		ArrayList<Integer> collection1 = new ArrayList<Integer>();
		collection1.getClass().getMethod("add", Object.class).invoke(collection1, new Date());
		System.out.println(collection1.get(0));
		ArrayList<Date> collection3 = new ArrayList<Date>();
		collection3.getClass().getMethod("add", Object.class).invoke(collection3, "hello");
		collection3.getClass().getMethod("add", Object.class).invoke(collection3, 17);
		System.out.println(collection3.get(0) + ":" + collection3.get(1));
		// 当参数化泛型类型为String时,运行时能添加任意类型,但取出时出现类型转换
		ArrayList<String> collection2 = new ArrayList<String>();
		Object obj = collection2.getClass().getMethod("add", Object.class).invoke(collection2, 12);
		// System.out.println(collection2.get(0));
		Object obj1 = collection2.getClass().getMethod("add", Object.class)
			.invoke(collection2, new Date());
		// System.out.println(collection2.get(0));
		// 返回两个true,说明都添加成功。
		System.out.println(obj + ":" + obj1);
		// 是在取出的时候出问题。
		Iterator it = collection2.iterator();
		while (it.hasNext())
		{
			Object object = (Object) it.next();
			System.out.println(object);
		}

		// ------------------打印Array.class中的方法-------------------
		Class clazz2 = Array.class;
		Method[] methods2 = clazz2.getDeclaredMethods();
		// System.out.println("-------Array.class中的方法-------");
		System.out.println(clazz2.getName());
		for (Method method : methods2)
		{
			// System.out.println(method.getName());
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值