J2EE基础 07 (反射)

这篇博客详细介绍了Java反射机制,包括如何获取类信息、反射实例化、动态方法调用以及读写属性。通过类名.class、Class.forName()和对象.getClass()三种方式获取类信息。讲解了构造方法的获取和调用,以及公有和私有方法的动态调用。同时,展示了如何使用反射进行属性的读写操作。
摘要由CSDN通过智能技术生成

 目录

【思维导图】

一、什么是反射?

二、类类

三、反射实例化

四、反射动态方法调用

五、反射读写属性


【思维导图】

一、什么是反射?

eg:

狗类    旺财    
猫类    肥波    
旺财是狗类的实例
肥波是猫类的实例
那么狗类是谁的实例?
狗类是类类的实例

 反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法。

二、类类

Student实体类代码块展示:

package com.chenchen.reflect;

/**
 * 实体类:
 * 学生类
 * @author ChenChen
 *@date 2022年6月16日 下午3:57:24
 */
public class Student {
	private String sid;

	private String sname;

	public Integer age;
	
	static{
		System.out.println("加载进jvm中!");
	}

	public Student() {
		super();
		System.out.println("调用无参构造方法创建了一个学生对象");
	}

	public Student(String sid) {
		super();
		this.sid = sid;
		System.out.println("调用带一个参数的构造方法创建了一个学生对象");
	}

	public Student(String sid, String sname) {
		super();
		this.sid = sid;
		this.sname = sname;
		System.out.println("调用带二个参数的构造方法创建了一个学生对象");
	}

	@SuppressWarnings("unused")
	private Student(Integer age) {
		System.out.println("调用Student类私有的构造方法创建一个学生对象");
		this.age = age;
	}

	public String getSid() {
		return sid;
	}

	public void setSid(String sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public void hello() {
		System.out.println("你好!我是" + this.sname);
	}

	public void hello(String name) {
		System.out.println(name + "你好!我是" + this.sname);
	}

	@SuppressWarnings("unused")
	private Integer add(Integer a, Integer b) {
		return new Integer(a.intValue() + b.intValue());
	}
}

获取类类的三种方式:

1、类名.class

 代码块展示:

package com.chenchen.reflect;

import com.mysql.jdbc.Driver;

/**
 * 如何获得类类
 * 获取到student类的类
 * 	1、类.class
 * @author ChenChen
 *@date 2022年6月16日 下午3:58:31
 */
public class Demo1 {
	public static void main(String[] args) throws Exception {
//		1.类.class
		Class c =  Student.class;
	}
}

2、Class.forName(完整类名)

代码块展示:

package com.chenchen.reflect;

import com.mysql.jdbc.Driver;

/**
 * 如何获得类类
 * 获取到student类的类
 * 	2、类实例.getClass()
 * @author ChenChen
 *@date 2022年6月16日 下午3:58:31
 */
public class Demo1 {
	public static void main(String[] args) throws Exception {
//		注意:确定本工程有这个实体类
//		2.类实例.getClass
		Student stu = new Student();
		Class c1 = stu.getClass();
}
}

结果展示:

 注意:前文的Student类的构造方法

3、对象.getClass()

代码展示:

package com.chenchen.reflect;

import com.mysql.jdbc.Driver;

/**
 * 如何获得类类
 * 获取到student类的类
 * 	3、Class.forName("类的全路径名")
 * @author ChenChen
 *@date 2022年6月16日 下午3:58:31
 */
public class Demo1 {
	public static void main(String[] args) throws Exception {
//		本工程没有这个类也可以编译通过
//		3、Class.forName("类的全路径名");
		Class c2 = Class.forName("com.chenchen.reflect.Student");
	}
}

结果输出:

 注意:本工程没有这个类时,编译也可以通过。

三、反射实例化

①getConstructor        ——>constructor只能够获取共有的构造方法

②getDeclaredConstructor        ——>获取私有的构造器

③newInstance       ——>获取无参的构造方法

提问:

 *     1、如何获取无参数 共有的构造方法?

代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Constructor;

/**
 * 反射实例化
 * 	1、无参数 共有的构造方法
 * 	2、有参数 共有的构造方法
 * 	3、有多个参数  共有的构造方法
 * 	4、私有的构造方法
 * @author ChenChen
 *@date 2022年6月16日 下午5:59:31
 */
public class Demo2 {
	public static void main(String[] args) throws Exception, Exception {
		
		//实例化一个学生对象
		Student stu = new Student();
//		-------------------------------------以下均为反射的方法实例化对象----------------
		
		//获取类类
		Class<? extends Student> clas = stu.getClass();
//		默认的是调用无参 公有的构造函数
//		1、如何获取无参数的共有的构造方法
		Student su1 = clas.newInstance();
	}
}

结果输出:



 *     2、如何获取有参数 共有的构造方法?

代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Constructor;

/**
 * 反射实例化
 * 	2、有参数 共有的构造方法
 * @author ChenChen
 *@date 2022年6月16日 下午5:59:31
 */
public class Demo2 {
	public static void main(String[] args) throws Exception, Exception {
		
		//实例化一个学生对象
		Student stu = new Student();
//		-------------------------------------一下均为反射的方法实例化对象----------
		
		//获取类类
		Class<? extends Student> clas = stu.getClass();
//		2、有参数 共有的构造方法
		//拿到构造器对象    三个.代表可以传1个2个..n个参数-->拿到一个参数为String的构造器对象
		Constructor<? extends Student> cons = clas.getConstructor(String.class);
		Student stu2 = cons.newInstance("s001");
	}
}

结果输出:


 *     3、如何获取有多个参数  共有的构造方法?

代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Constructor;

/**
 * 反射实例化
 * 	3、有多个参数  共有的构造方法
 * @author ChenChen
 *@date 2022年6月16日 下午5:59:31
 */
public class Demo2 {
	public static void main(String[] args) throws Exception, Exception {
		
		//实例化一个学生对象
		Student stu = new Student();
//		-------------------------------------一下均为反射的方法实例化对象----------
		
		//获取类类
		Class<? extends Student> clas = stu.getClass();
//		3、如何获取有多个参数的共有的构造方法
		Constructor<? extends Student> cons1 = clas.getConstructor(String.class,String.class);
		Student stu3 = cons1.newInstance("w001","吴彦祖");
	}
}

结果输出:


 *     4、如何获取私有的构造方法?

 代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Constructor;

/**
 * 反射实例化
 * 	4、私有的构造方法
 * @author ChenChen
 *@date 2022年6月16日 下午5:59:31
 */
public class Demo2 {
	public static void main(String[] args) throws Exception, Exception {
		//实例化一个学生对象
		Student stu = new Student();
//		-------------------------------------一下均为反射的方法实例化对象----------
		//获取类类
		Class<? extends Student> clas = stu.getClass();
//		4、如何获取私有的构造方法
//		注意:constructor只能够获取共有的构造方法,要获取私有的构造器getDeclaredConstructor
		Constructor<? extends Student> cons2 =clas.getDeclaredConstructor(Integer.class);
//		打开访问权限
		cons2.setAccessible(true);
		Student stu4 = cons2.newInstance(18);
	}
}

 结果输出:

注意:获取私有的构造方法时,不仅需要私有的构造器【getDeclaredConstructor】,还需要打开权限 【setAccessible(true)】

四、反射动态方法调用

①getMethod        ——>调用公有方法

②getDeclaredMethod        ——>调用私有方法

*     1、如何调用无参的 公有方法

代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Method;

/**
 * 反射动态调用方法
 * 	1、调用无参的 共有方法
 * @author ChenChen
 *@date 2022年6月16日 下午6:28:56
 */
public class Demo3 {
	public static void main(String[] args) throws Exception, Exception {
		 /**
		  * 1、先拿到类类
		  * 2、拿到方法对象
		  * 3.调用对应的方法
		  */
		
//		1、先拿到类类
		Class<Student> clz = Student.class;
//		name:方法名   parameterTypes:方法对应的参数
//		调用1个有参的 共有方法
		Method m1 = clz.getMethod("hello");
//		调用对应的方法
//		第一个参数:那个类实例	第二个参数:方法调用时的实参
//		m1.invoke方法调用的返回值就是方法对象本身的返回值
		Object invoke = m1.invoke(clz.newInstance());
	}
}

结果输出:


 *     2、如何调用1个有参的 公有方法

 代码块展示

package com.chenchen.reflect;

import java.lang.reflect.Method;

/**
 * 反射动态调用方法
 * 	2、调用1个有参的 共有方法
 * @author ChenChen
 *@date 2022年6月16日 下午6:28:56
 */
public class Demo3 {
	public static void main(String[] args) throws Exception, Exception {
		 /**
		  * 1、先拿到类类
		  * 2、拿到方法对象
		  * 3.调用对应的方法
		  */
		
//		调用1个有参的共有方法
		Method m2 = clz.getMethod("hello", String.class);
		Object invoke2 = m2.invoke(clz.newInstance(),"吴彦祖");
		System.out.println(invoke2);
	}
}

结果输出:

 
 *     3、如何调用私有方法

 代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Method;

/**
 * 反射动态调用方法
 * 	3、调用私有方法
 * @author ChenChen
 *@date 2022年6月16日 下午6:28:56
 */
public class Demo3 {
	public static void main(String[] args) throws Exception, Exception {
		 /**
		  * 1、先拿到类类
		  * 2、拿到方法对象
		  * 3.调用对应的方法
		  */
	
//		调用私有方法
		Method m3 = clz.getDeclaredMethod("add", Integer.class,Integer.class);
		m3.setAccessible(true);
		Object invoke3 = m3.invoke(clz.newInstance(), 5,5);
		System.out.println(invoke3);
	}
}

结果输出:


五、反射读写属性

代码块展示:

package com.chenchen.reflect;

import java.lang.reflect.Field;

/**
 * 反射读写属性
 * @author ChenChen
 *@date 2022年6月16日 下午7:47:14
 */
public class Demo4 {
	public static void main(String[] args) throws Exception, Exception {
		Student stu = new Student("s001","吴彦祖");
		stu.age=18;
//		需求:要拿到这个学生所有的属性及属性值
//		System.out.println("age"+stu.age);
//		System.out.println("sname"+stu.getSname());
//		System.out.println("sid"+stu.getSid());
		
		/**
		 * 上述代码存在的问题
		 * 1.你事先得知道这个类有哪些属性
		 * 2.假设Student有30个属性呢?那么就要写30行
		 * 对于未知的东西无法获取
		 */
		
//		一切反射从类类开始
		Class<? extends Student> clz = stu.getClass();
		//拿到的是当前类的所有属性对象
		Field[] files = clz.getDeclaredFields();//可以拿到私有的构造器也可以拿到公有的构造器
		System.out.println("数组的长度"+files.length);
		for (Field f : files) {//f-->代表每次循环的属性对象
			//打开访问器
			f.setAccessible(true);
			//通过属性对象拿到属性名称
			System.out.println("属性名称:"+f.getName());
			//拿到当前的属性对象的属性值
			System.out.println("属性的值:"+f.get(stu));
		}
	}
}

结果输出:


ok,本章内容分享完毕,下期预告JSP标签的解析知识点,希望对您有帮助,若本文章内容出现错误,还望指正,感谢您的观看。 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值