折纸的不归路(18)

一.反射

反射的使用方法

1.学会获得镜像对象,(三种方式)

a.我们知道类的全限类名 com.briup.dat06.Student
Class.forName(全限类名);
b.只知道类的类名 Student
Student.class;
c.只知道有个对象的名字,stu1
stu1.getClass();

2.创建一个测试的例子 ReflectTest.java

java.lang.Class的实例,叫做镜像对象
java.lang.reflect
Field
Method
Construct
Modified

3.功能具体测试参见代码

反射的相关测试

package day16;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

import java.util.*;


/**
 * 测试反射的功能
 * 
 * @author Acer
 *
 */
 @Resource
@SuppressWarnings("unchecked")
public class ReflectTest {
	public int i;
	private double d;
	static String s;
	protected Map<Integer, String> map;
	public List<String> list = new ArrayList<String>();

	public ReflectTest() {
		System.out.println("调用空参构造器");
		this.i = 10;
		this.d = 20.0;
		this.s = "hello";
	}

	public ReflectTest(String s) {
		System.out.println("调用单参构造器");
		this.s = s;
	}

	public void show() {
		System.out.println("这是一个空参的方法");
	}

	private String show(String s) {
		System.out.println(this.s);
		System.out.println("这是一个String参数的方法");
		return s;
	}
	//给D添加一个get方法
	public double getD() {
		return d;
	}

	public void setD(double d) {
		this.d = d;
	}

	class inner1 {

	}

	private class Inner2 {

	}

	public static void main(String[] args) throws Exception {
		// 使用三种方式来获得ReflectTest的镜像对象(Class的实例)
		// 1.day16.ReflectTest
		Class<?> clazz1 = Class.forName("day16.ReflectTest");
		// //2.ReflectTest
		// Class<ReflectTest> clazz2 = ReflectTest.class;
		// //3.只知道对象的名字
		// ReflectTest rt = new ReflectTest();
		// Class<?> clazz3 = rt.getClass();
		System.out.println(clazz1);
		// System.out.println(clazz2);
		// System.out.println(clazz3);

		System.out.println("==========属性===========");
		// Field[] fs = clazz1.getFields();//获取的所有public属性
		Field[] fs = clazz1.getDeclaredFields();
		System.out.println(fs.length);
		for (Field field : fs) {
			System.out.println(field);
			System.out.println("----------------");
			System.out.println(field.getName());
			System.out.println(field.getType());
			System.out.println(field.getModifiers());
		}
		System.out.println("==========方法==========");
		// Method[] ms = clazz1.getMethods();//获取所有的public方法,包括本类和父类的
		Method[] ms = clazz1.getDeclaredMethods();// 获得本类的所有方法

		for (Method method : ms) {
			System.out.println(method);
		}

		System.out.println("=========构造器========");
		Constructor<?>[] cs = clazz1.getConstructors();
		for (Constructor<?> constructor : cs) {
			System.out.println(constructor);
		}

		System.out.println("=========内部类========");
		Class<?>[] inners = clazz1.getDeclaredClasses();
		for (Class<?> class1 : inners) {
			System.out.println(class1);
		}

		// 小小的需求
		// 获取第一个内部类的外部类名称

		Class<?> innerOne = inners[0];
		String className = innerOne.getName();
		// 注意一下内部类的全限类名方式
		// class day16.ReflectTest$inner1
		Class<?> inneroo = Class.forName(className);
		// 通过内部类来获得外部类的Class实例
		Class<?> outClass = innerOne.getDeclaringClass();
		System.out.println(outClass.getName());

		System.out.println("==========注解=========");
		Annotation[] as = clazz1.getDeclaredAnnotations();
		for (Annotation annotation : as) {
			System.out.println(annotation);
		}

		System.out.println("===================");
		
		// 反射主要是在程序的运行阶段动态的修改信息
		// 使用反射来创建对象
		// 1.使用默认的构造器
		// ReflectTest rt = new ReflectTest(); //原始的创建方式
		// 用反射产生的新实例是Object的实例
		Object obj = clazz1.newInstance();
		// 需要在验证时候进行类型转换
		ReflectTest rt1 = null;
		if (obj instanceof ReflectTest) {
			rt1 = (ReflectTest) obj;
		}
		rt1.show();
		System.out.println(rt1.show("String"));
		System.out.println("============构造器创建对象=============");
		
		
		
		// 2.使用指定的构造器
		//首先要获得所制定的构造器
//		ReflectTest rt2 = new ReflectTest("Hello, World!");
		Constructor<?> c1 = clazz1.getDeclaredConstructor(String.class);
		//使用制定的构造器进行对象的创建
		ReflectTest rt2  = (ReflectTest) c1.newInstance("Hello, World!");
		
		
		
		System.out.println("=============反射调用方法=================");
		//调用方法之前先获得方法
		Method m1 = clazz1.getDeclaredMethod("show", null);
		Method m2 = clazz1.getDeclaredMethod("show", String.class);
		//使用对象去调用 invoke(调用方法的方法)
		m1.invoke(rt2, null);//rt2.show();
		m2.invoke(rt2, "tom");//rt2.show("tom");
		//假设运行时期给泛型添加不同的数据类型
		
		
		System.out.println("============属性值的访问=========");
		//先获得想要修改的属性
		System.out.println(rt2.s);
		Field f1 = clazz1.getDeclaredField("s");
		f1.set(rt2, "Hello, Tom!");
		System.out.println(rt2.s);
		
//		以上的部分要求掌握
//		以下的部分为拓展
		
		
		System.out.println("==========访问泛型=========");
		//先要获得泛型类型的属性对象
		Field f2 = clazz1.getDeclaredField("map");
		Type gf = f2.getGenericType();
		if(gf instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType)gf;
			System.out.println("原始类型"+pt.getRawType().getTypeName());
			//获取泛型的类型参数
			Type[] ata = pt.getActualTypeArguments();
			for(int i=0;i<ata.length;i++) {
				System.out.println("第"+(i+1)+"个参数类型为"+ata[i].getTypeName());
			}
		}
		
		
		System.out.println("===========数组========");
		//使用反射来动态创建数组和访问数组对象 Array
		Object o = Array.newInstance(String.class, 10);
		//数组中添加元素
		Array.set(o, 0, "hello");
		Array.set(o, 1, "world");
		Array.set(o, 2, "tom");
		Array.set(o, 3, "jerry");
		//获得元素
		System.out.println(Array.get(o, 2));
		//获得数组长度
		System.out.println(Array.getLength(o));
		
		
		System.out.println("=============其他功能===========");
		System.out.println(clazz1.getPackage());
		System.out.println(clazz1.getSuperclass());
		System.out.println(Arrays.toString(clazz1.getInterfaces()));
	}

}

得到的输出结果分别为

class day16.ReflectTest
==========属性===========
5
public int day16.ReflectTest.i
----------------
i
int
1
private double day16.ReflectTest.d
----------------
d
double
2
static java.lang.String day16.ReflectTest.s
----------------
s
class java.lang.String
8
protected java.util.Map day16.ReflectTest.map
----------------
map
interface java.util.Map
4
public java.util.List day16.ReflectTest.list
----------------
list
interface java.util.List
1
==========方法==========
public static void day16.ReflectTest.main(java.lang.String[]) throws java.lang.Exception
public void day16.ReflectTest.setD(double)
public double day16.ReflectTest.getD()
private java.lang.String day16.ReflectTest.show(java.lang.String)
public void day16.ReflectTest.show()
=========构造器========
public day16.ReflectTest()
public day16.ReflectTest(java.lang.String)
=========内部类========
class day16.ReflectTest$Inner2
class day16.ReflectTest$inner1
day16.ReflectTest
==========注解=========
@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)
===================
调用空参构造器
这是一个空参的方法
hello
这是一个String参数的方法
String
============构造器创建对象=============
调用单参构造器
=============反射调用方法=================
这是一个空参的方法
Hello, World!
这是一个String参数的方法
============属性值的访问=========
Hello, World!
Hello, Tom!
==========访问泛型=========
原始类型java.util.Map
第1个参数类型为java.lang.Integer
第2个参数类型为java.lang.String
===========数组========
tom
10
=============其他功能===========
package day16
class java.lang.Object
[]

二.异常

异常的分类
编译阶段的异常,受检查异常CheckedException
运行阶段的异常,运行时异常RuntimeException

三.心得

今天的内容依然是比较好接受的,主要就是在学习一些反射使用的方法,今天早上对昨天的学生管理系统进行了相关功能的完善,把输入错误数据的情况都补充了一下,同时对年龄和性别的范围做了一些相关的限制,新的源码已经在上一篇博客中更新.明天就是令人激动的周五了,这周总算能舒舒服服的休息休息了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值