java反射机制的复习

转载出处:https://blog.csdn.net/sinat_38259539/article/details/71799078

1、Class类是被final修饰的类不能被继承
2、Class类的实例表示正在运行的Java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象 。基本的Java类型(boolean,byte,char,short,int,long,float和double)和关键字void也表示为Class对象。Class对象没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的


一、获取构造方法并使用

自己写的练习demo

Student类

public class Student {
	//--------构造方法---------------
	//(默认的构造方法)
	Student(String str) {
		System.out.println("默认的构造方法="+str);
	}
	
	//无参的构造方法
	public Student(){
		System.out.println("调用了公有,无参构造方法");
	}
	
	//有一个参数的构造方法
	public Student(char name){
		System.out.println("姓名:"+name);
	}
	
	//有多个参数的构造方法
	public Student(String name,int age){
		System.out.println("姓名:"+name + "年龄:"+age);
	}
	
	//受保护的构造方法
	protected Student(boolean n){
		System.out.println("受保护的构造方法n = "+n);
	}
	
	//私有方法
	private Student(int age){
		System.out.println("私有的构造方法 年龄:"+age);
	}
}

测试类

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

public class Constructors {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class class1 = Class.forName("com.sunj.test.Student");
		//获取所有共有的构造方法
		System.out.println("获取所有公有的构造方法");
		Constructor [] con1=class1.getConstructors();
		for (Constructor c1 : con1) {
			System.out.println(c1);
		}
		
		//获取所有的构造方法
		System.out.println("获取所有的构造方法,不管它的修饰符是公有,默认,保护,私有");
		Constructor [] con2 = class1.getDeclaredConstructors();
		for (Constructor c2 : con2) {
			System.out.println(c2);
		}
		
		System.out.println("获取公有,无参的构造方法");
		Constructor con3 = class1.getConstructor(null);//返回的是该构造方法的类对象
		System.out.println(con3);
		Object object = con3.newInstance(null);//调用该方法
		
		System.out.println("获取私有构造方法并调用");
		Constructor con4 = class1.getDeclaredConstructor(int.class);
		System.out.println(con4);
		//调用构造方法
		con4.setAccessible(true);//忽略掉访问修饰符
		object = con4.newInstance(22);
		
	}

}

getDeclaredConstructors和getConstructors方法的区别

1、getDeclaredConstructors是获取所有的构造方法,而getConstructor是获取所有的公有方法

2、两者都可以通过传参拿到指定的构造方法,这里的参数是构造方法的参数的类型,比如构造方法传的String name,那么这里就传的是String.class

 

调用方法:

1.获取构造方法:

  1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
  2).获取单个的方法,并调用:
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

  调用构造方法:

Constructor-->newInstance(Object... initargs)

 

2、newInstance是 Constructor类的方法(管理构造函数的类)

api的解释为:

newInstance(Object... initargs)
           使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用

二、获取成员变量

public class User {
	public User(){
		
	}
	//*************字段*************//
	public String name;
	protected int age;
	char sex;
	private String phoneNum;
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", sex=" + sex + ", phoneNum=" + phoneNum + "]";
	}
	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;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	public String getPhoneNum() {
		return phoneNum;
	}
	public void setPhoneNum(String phoneNum) {
		this.phoneNum = phoneNum;
	}
	
	
}

测试类

import java.lang.reflect.Field;

public class Fields {
	public static void main(String[] args) throws Exception {
		//1、获取class对象
		Class class1 = Class.forName("com.sunj.test.User");
		//2、获取字段
		System.out.println("获取所有的公有字段");
		Field[] f1 = class1.getFields();
		for (Field field1 : f1) {
			System.out.println(field1);
		}
		//3、获取所有的字段
		System.out.println("获取所有的字段");
		Field [] f2 = class1.getDeclaredFields();
		for (Field field2 : f2) {
			System.out.println(field2);
		}
		
		//4、获取公有字段并调用
		System.out.println("获取公有字段并调用");
		Field field1 = class1.getField("name");
		System.out.println(field1);
		//获取一个对象
		Object object = class1.getConstructor().newInstance();//相当于User user = new User();
		//为字段设值
		field1.set(object, "花花");//相当于user.setName("花花");
		//验证
		User user = (User)object;
		System.out.println(user.name);
		
		//5、获取私有字段并调用
		System.out.println("获取私有字段并调用");
		Field fi = class1.getDeclaredField("phoneNum");
		System.out.println(fi);
		fi.setAccessible(true);//忽略私有属性
		fi.set(object, "18712111");
		user = (User)object;
		System.out.println(user.getPhoneNum());
	}

}

调用字段时,第一个参数:要传入设置的对象,第二个参数:要传入实参,就相当于平时我们写的对象的set方法

三、获取成员方法并调用

public class Student {
	// **************成员方法***************//
	public void show1(String s) {
		System.out.println("调用了:公有的,String参数的show1(): s = " + s);
	}

	protected void show2() {
		System.out.println("调用了:受保护的,无参的show2()");
	}

	void show3() {
		System.out.println("调用了:默认的,无参的show3()");
	}

	private String show4(int age) {
		System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " + age);
		return "abcd";
	}

}

测试类:

import java.lang.reflect.Method;

public class Methods {
	public static void main(String[] args) throws Exception {
		Class class1 = Class.forName("com.sunj.test.Student");

		// 1、获取所有的公有方法
		System.out.println("获取所有的公有方法");
		Method[] methods = class1.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}

		// 2、获取搜有的方法
		System.out.println("获取所有的方法");
		Method[] methods2 = class1.getDeclaredMethods();
		for (Method method : methods2) {
			System.out.println(method);
		}

		// 3、获取公有的show1方法
		System.out.println("获取公有的show1方法");
		Method m1 = class1.getMethod("show1", String.class);
		Object obj = class1.getConstructor().newInstance();
		m1.invoke(obj, "你好呐");

		// 获取私有的show4方法
		System.out.println("获取私有的show4方法");
		Method m2 = class1.getDeclaredMethod("show4", int.class);//调用定制方法(包括私有的),需要传入两个参数,第一个是调用的方法名称,第二个是方法的形参类型。
		m2.setAccessible(true);//解除私有绑定
		Object result = m2.invoke(obj, 18);//调用时需要两个参数,一个是要调用的对象(获取有反射),一个是实参
		System.out.println(result);


	}

}

注意:获取公有方法时,连父类Object的公有方法也会打印出来

           而获取所有的方法时,Object类的方法并没有打印出来。

四、反射main方法

public class Student {
	public static void main(String[] args) {
		System.out.println("main方法已执行"  + args[0]);
	}

}

测试类

import java.lang.reflect.Method;

public class Methods {
	public static void main(String[] args) throws Exception {
		Class class1 = Class.forName("com.sunj.test.Student");

	//获取main方法
		Method methodMain = class1.getMethod("main", String[].class);
		Object obj = class1.getConstructor().newInstance();
		methodMain.invoke(null,(Object)new String[]{"a","b","c"});
	}

}

反射main方法的调用:

methodMain.invoke(null,(Object)new String[]{"a","b","c"}); 

五、反射方法的其它使用之---通过反射运行配置文件内容

package com.sunj.test;

public class Student {
	public void show(){
		System.out.println("is show()");
	}

}

配置文件

className = com.sunj.test.Student
methodName = show

测试类

import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改
 * 我们只需要将新类发送给客户端,并修改配置文件
 * @author vela_sun
 *
 */
public class Demo {
	public static void main(String[] args) throws Exception{
		//通过反射获取class对象
		Class class1 = Class.forName(getValue("className"));
		//获取show方法
		Object object = class1.getConstructor().newInstance();
		Method method = class1.getMethod(getValue("methodName"));
		method.invoke(object);
	}
	
	//此方法接收一个key,在配置文件获取相应的value
	public static String getValue(String key) throws Exception{
		Properties properties = new Properties();//获取配置文件
		FileReader in = new FileReader("src\\main\\java\\com\\sunj\\test\\pro.txt");
		properties.load(in);
		in.close();
		return properties.getProperty(key);
	}
}
import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改
 * 我们只需要将新类发送给客户端,并修改配置文件
 * @author vela_sun
 *
 */
public class Demo {
	public static void main(String[] args) throws Exception{
		//通过反射获取class对象
		Class class1 = Class.forName(getValue("className"));
		//获取show方法
		Object object = class1.getConstructor().newInstance();
		Method method = class1.getMethod(getValue("methodName"));
		method.invoke(object);
	}
	
	//此方法接收一个key,在配置文件获取相应的value
	public static String getValue(String key) throws Exception{
		Properties properties = new Properties();//获取配置文件
		FileReader in = new FileReader("src\\main\\java\\com\\sunj\\test\\pro.txt");
		properties.load(in);
		in.close();
		return properties.getProperty(key);
	}
}

注意:配置文件和测试类在同一个目录,获取属性文件时的路径也不能直接写名字

当我们升级这个系统时,不要Student类,而需要新写一个Student2的类时,这时只需要更改pro.txt的文件内容就可以了。代码就一点不用改动

六、反射方法的其它使用之---通过反射越过泛型检查

import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * 通过反射机制越过泛型检查
 * 例如,有一个String泛型的集合,怎样像这个集合添加一个Integer类型的数据
 * @author vela_sun
 *
 */
public class Demo {
	public static void main(String[] args) throws Exception{
		ArrayList<String> list = new ArrayList<String>();
		list.add("aa");
		list.add("bb");
		list.add("cc");
		//获取Arraylist的Class对象,反向的调用add()方法,添加数据
		Class class1 = list.getClass();
		Method method = class1.getMethod("add", Object.class);
		method.invoke(list, 100);
		for (Object oo : list) {
			System.out.println(oo);
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
综合小区管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、车位管理、车位分配管理、出入管理、字典管理、房屋管理、物业费缴纳管理、公告管理、物业人员投诉管理、我的私信管理、物业人员管理、用户管理、管理员管理。用户的功能包括管理部门以及部门岗位信息,管理招聘信息,培训信息,薪资信息等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 综合小区管理系统管理系统可以提高综合小区管理系统信息管理问题的解决效率,优化综合小区管理系统信息处理流程,保证综合小区管理系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理综合小区管理系统信息,包括出入管理,报修管理,报修管理,物业费缴纳等,可以管理操作员。 出入管理界面,管理员在出入管理界面中可以对界面中显示,可以对招聘信息的招聘状态进行查看,可以添加新的招聘信息等。报修管理界面,管理员在报修管理界面中查看奖罚种类信息,奖罚描述信息,新增奖惩信息等。车位管理界面,管理员在车位管理界面中新增。公告管理界面,管理员在公告管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值