首页 > 编程语言 >Java之反射(重要 · 下)

Java之反射(重要 · 下)

时间:2023-12-10 13:31:47浏览次数:40  
标签:反射 重要 String age Class Java class1 public name

创建对象

Class类提供了一个实例方法newInstance(),通过该方法可以创建对象,使用起来比较简单。

调用构造方法

package java2023_08_10;

import java.lang.reflect.Constructor;

public class ConstructorReflect {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			@SuppressWarnings("rawtypes")
			Class class1 = Class.forName("java.lang.String");
			// 调用默认方法
			@SuppressWarnings({ "unchecked", "unused" })
			String string = (String) class1.getDeclaredConstructor().newInstance();
			@SuppressWarnings("rawtypes")
      //设置构造方法参数类型
			Class[] params = new Class[1];
      //第一个参数是string
			params[0] = String.class;
			@SuppressWarnings({ "unchecked", "rawtypes" })
      //获取与参数对应的构造方法
			Constructor constructor = class1.getConstructor(params);
      //为构造方法传递参数
			Object[] objects = new Object[1];
      //第一个参数传递“Hello”
			objects[0] = "Hello";
      //调用非默认构造方法,构造方法第一个参数是String类型
			String str = (String) constructor.newInstance(objects);
			System.out.println(str);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Java之反射(重要 · 下)_反射

案例:依赖注入实现

在一些框架开发中经常将要实例化的类名保存到配置文件中,在运行时从配置文件中读取类名字符串,然后动态创建对象,建立依赖关系。采用new创建对象依赖关系是在编译期建立的,反射机制能够将依赖关系推迟到运行时建立,这种依赖关系动态注入进来称为依赖注入

package java2023_08_10;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;

public class DependencyInjection {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			String className = readClassName();
			Class class1 = Class.forName(className);
			// 指定参数类型
			Class[] params = new Class[3];
			params[0] = String.class;
			params[1] = int.class;
			params[2] = String.class;
			// 获取对应参数的构造方法
			Constructor constructor = class1.getConstructor(params);
			Object[] argObjects = new Object[3];
			argObjects[0] = "Amy";
			argObjects[1] = "15";
			argObjects[3] = "奥利萨大学";
			// 调用非默认构造方法
			Object p = constructor.newInstance(argObjects);
			System.out.println(p);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private static String readClassName() {
		// TODO Auto-generated method stub
		FileInputStream fis = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		try {
			fis = new FileInputStream("Configuration.ini");
			isr = new InputStreamReader(fis);
			br = new BufferedReader(isr);
			// 读取文件中的一行数据
			String str = br.readLine();
			return str;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("处理IOException...");
			e.printStackTrace();
		}
		return null;
	}
}

调用方法

通过反射还可以调用方法,这与调用构造方法类似。调用方法需要使用Method对象,它对应着一个方法。获得Method对象需要使用Class类的如下方法:

  • Method[] getMethods()
  • Method[] getDeclaredMethods()
  • Method getMethod(String name,Class...parameterTypes)
  • Method getDeclaredMethod(String name,Class...parameterTypes
    )

实例代码如下:

Person.java

package java2023_08_10;

public class Person {
	private String name;
	private int age;

	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 void setNameAndAge(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

现在编写一个程序通过反射机制调用Person类的setNameAndAge()和getName()方法。

PersonTest.java

package java2023_08_10;

import java.lang.reflect.Method;

public class PersonTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			Class class1 = Class.forName("java2023_08_10.Person");
			Person person = (Person) class1.getDeclaredConstructor().newInstance();
			System.out.println(person);
			Class[] params = new Class[2];
			params[0] = String.class;
			params[1] = int.class;
			// 获取setNameAndAge方法对象
			Method method = class1.getMethod("setNameAndAge", params);
			Object[] argObjects = new Object[2];
			argObjects[0] = "Amy";
			argObjects[1] = 18;
			// 调用setNameAndAge方法
			method.invoke(person, argObjects);
			System.out.println(person);
			// 获取getName方法对象
			method = class1.getMethod("getName");
			// 调用getName方法
			Object result = method.invoke(person);
			System.out.println(result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Java之反射(重要 · 下)_java_02

调用成员方法

通过反射机制还可以调用成员变量,调用方法需要使用Field对象,它对应着一个方法。获得Field对象需要使用Class类的如下方法:

  • Field[] getFields()
  • Field[] getDeclaredFileds()
  • Field getField(String name)
  • Field getDeclaredField(String name)

实例代码如下:

Person.java

package java2023_08_10;

public class Person {
	private String name = "";
	private int age;

	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;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

}

PersonTestTwo.java

package java2023_08_10;

import java.lang.reflect.Field;

public class PersonTestTwo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			Class class1 = Class.forName("java2023_08_10.Person");
			Person person = (Person) class1.getDeclaredConstructor().newInstance();

			Field name = class1.getDeclaredField("name");
			name.setAccessible(true);
			name.set(person, "Tony");

			Field age = class1.getDeclaredField("age");
			age.setAccessible(true);
			age.set(person, 18);

			System.out.printf("[name:%s, age:%d]", name.get(person), age.get(person));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Java之反射(重要 · 下)_反射_03

通过本章的学习,我们应该清楚什么时候使用反射。

标签:反射,重要,String,age,Class,Java,class1,public,name
From: https://blog.51cto.com/u_16174658/8760697

相关文章

  • java-打包编译常用命令
    java-打包编译常用命令 1.maven预编译(打包检查异常) 在上到测试环境或者生产环境之前,先在本地打包检查异常: mvncleaninstall-Dmaven.test.skip=true-X  2.maven打包 一般用IDEA上的maven工具按钮: 如果打包失败则可以用下面的命令: mvncleaninsta......
  • java-数据结构
    数据结构A:栈先进后出B:队列先进先出C:数组查询快,增删慢D:链表查询慢,增删快List的三个实现类(1)List的三个实现类特点A:ArrayList底层数据结构是数组,查询快,增删慢线程不安全,效率高B:Vector底层数据结构是数组,查询快,增删慢线程安全,效率低C:LinkedList底层数据结......
  • Java中<where>和<if>标签的组合使用
     在Java中,并没有<where>和<if>标签的组合使用。这两个标签不是Java编程语言或Java标准库的一部分,它们可能是你所使用的特定框架或库提供的自定义标签。如果你正在使用某个特定的Java框架或模板引擎(如MyBatis、Thymeleaf等),这些框架或引擎可能提供了自定义标签,使得在代码中使用......
  • Java入门项目--蚂蚁爱购
    简介这是一个靠谱的Java入门项目实战,名字叫蚂蚁爱购。从零开发项目,视频加文档,十天就能学会开发JavaWeb项目,教程路线是:搭建环境=>安装软件=>创建项目=>添加依赖和配置=>通过表生成代码=>编写Java代码=>代码自测=>前后端联调=>准备找工作。学完即可成为合格的Java开发,心里有......
  • Java基于云端的云HIS服务平台源码
    云HIS是针对中小医疗机构推出的一套基于云端的云HIS服务平台,借助云his,将医院业务流程化,大大提高医院的服务效率和服务质量,为客户提供医院一体化的信息解决方案。云his主要功能:包含门诊收费管理,住院收费管理,门诊医生工作站,住院医生工作站,住院护士工作站,辅助检查科室管理,药房药品管......
  • java-数据和集合 and 数据结构
    1:数组:基本类型的数组:int[]引用类型的数组:Student[]2:Collection集合(掌握)(1)集合的由来我们学习的是面向对象的语言,而面向对象的语言常见的操作就是操作对象。为了方便我们对多个对象进行操作,我们可以使用对象数组来进行。但是对象数组的长度是固定的,不适应变化的需求,所......
  • Java入门项目--蚂蚁爱购
    ​ 简介这是一个靠谱的Java入门项目实战,名字叫蚂蚁爱购。从零开发项目,视频加文档,十天就能学会开发JavaWeb项目,教程路线是:搭建环境=>安装软件=>创建项目=>添加依赖和配置=>通过表生成代码=>编写Java代码=>代码自测=>前后端联调=>准备找工作。学完即可成为合格的Java开......
  • JAVA BLOG-3
    第一部分:对之前发布的第三阶段PTA题目集(1)前言:总结之前所涉及到的知识点、题量、难度等情况:知识点:第三阶段的知识点与前两个阶段相比多了很多,比如说多次接口的使用,Map与Set的使用,Arraylist排序的使用,正则表达式的使用,栈的实现及基本操作等等,与之前的简单的继承多态相比,知识点......
  • 【Java】删除List中的几行数据
    方法一: list.subList(from,to).clear();(注意不要超出list的长度范围)1List<Integer>list=newArrayList<>();2list.add(1);3list.add(2);4list.add(3);5list.add(4);6list.subList(0,2).clear();7System.out.println("list=>"+list);......
  • Java Swing
    Swing在Java中的使用:创建图形用户界面(GUI)的步骤和技巧Swing是Java的一个图形用户界面(GUI)工具包,它提供了创建窗口、对话框、按钮等GUI元素所需要的类和方法。下面我们将介绍Swing的基本使用方法,包括创建窗口、添加组件、事件处理等。一、创建窗口创建Swing应用程序的第一步是创......