写在前面的话:

  1. 参考资料:尚硅谷视频
  2. 本章内容:如何通过反射调用属性与方法【在前面文章的基础上拓展】
  3. IDE:eclipse
  4. JDK:Java8

目录

1.调用属性

1.1 调用声明为public的属性

1.2 调用非public的属性 

2.调用方法 

2.1 调用声明为public的方法

2.1.1 方法的返回类型为void

2.1.2 方法返回类型为:非void

2.1.3 调用静态方法 

 2.2 调用非public的方法

 3.使用构造器

3.1 无参构造器

3.2 有参构造器

 4.GitHub已上传代码


1.调用属性

1.1 调用声明为public的属性

主要分为5步骤:

  1. 创建Class类的实例 【点击这里,学习如何创建Class类的实例
  2. 获取构造器【点击这里,学习如何获取构造器
  3. 通过获取的构造器,创建对象
  4. 获取属性【核心点击这里,学习如何获取属性
  5. 调用获取到的属性,并通过设置来改变属性的值

代码示例

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

/*
 * 调用属性
 */

public class TestField {

	public static void main(String[] args) throws Exception {
		
		Class<Person> clazz = Person.class;
		
		//1.获取构造器
		Constructor<Person> person = clazz.getConstructor();
		
		//2.通过构造器创建一个对象
		Person p1 =  person.newInstance();
		
		//3.获取属性
		Field name =  clazz.getField("name");
		
		//4.对属性进行赋值
		name.set(p1, "张三");
		
		//5.打印输出该信息
		System.out.println(p1);
		
	}
}

效果截图:

1.2 调用非public的属性 

当然通过此方法,一样也可以调用声明为public的属性。

主要改变了两个地方:

  1. 获取属性,应该使用getDeclaredField()方法
  2. 设置属性可以访问,通过setAccessible()方法

代码示例

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

/*
 * 调用属性
 */

public class TestField {

	public static void main(String[] args) throws Exception {
		
		Class<Person> clazz = Person.class;
		
		//1.获取构造器
		Constructor<Person> person = clazz.getConstructor();
		
		//2.通过构造器创建一个对象
		Person p1 =  person.newInstance();
		System.out.println(p1);
		
		//3.获取属性
		Field address =  clazz.getDeclaredField("address");
		
		//4.将属性设定为可访问
		address.setAccessible(true);
		
		//4.对属性进行赋值
		address.set(p1, "中国重庆");
		
		//5.打印输出该信息
		System.out.println(p1);
		
	}
}

效果截图:

2.调用方法 

2.1 调用声明为public的方法

2.1.1 方法的返回类型为void

主要分为5步骤:(与调用属性非常相似,只是有些地方略有不同)

  1. 创建Class类的实例 【点击这里,学习如何创建Class类的实例
  2. 获取构造器【点击这里,学习如何获取构造器
  3. 通过获取的构造器,创建对象
  4. 获取方法【核心点击这里,学习如何获取方法
  5. 调用获取到的方法,通过invoke()方法来进行调用(与调用属性不同之处

代码示例

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

public class TestMethod {

	public static void main(String[] args) throws Exception{
		
		//1.创建Class类的实例
		Class<Person> clazz = Person.class;
		
		//2.获取构造器
		Constructor<Person> person =  clazz.getDeclaredConstructor();
		
		//3.创建对象
		Person p1 = person.newInstance();
		
		//4.获取方法
		Method method =  clazz.getMethod("show");
		
		//5.调用方法
		Object obj =  method.invoke(p1);
		
		//6.打印返回值【可有可无】
		System.out.println(obj);
		
	}
}

效果截图:

2.1.2 方法返回类型为:非void

说明:

  1. 如果调用的方法含有输出语句,就输出,否则调用invoke不起作用
  2. 调用的方法有返回值,在invoke()方法的后面进行输出返回值

代码示例

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

public class TestMethod {

	public static void main(String[] args) throws Exception{
		
		//1.创建Class类的实例
		Class<Person> clazz = Person.class;
		
		//2.获取构造器
		Constructor<Person> person =  clazz.getDeclaredConstructor();
		
		//3.创建对象
		Person p1 = person.newInstance();
		
		//4.获取方法
		Method method =  clazz.getMethod("toString");
		
		//5.调用方法
		Object obj =  method.invoke(p1);//没有输出语句,控制台不显示任何信息
		
		//6.打印返回值【必要】
		System.out.println(obj);//Person [name=null, age=0, sex=null, address=null]
		
	}
}

效果截图

2.1.3 调用静态方法 

说明:

  1. 在invoke()方法中,参数直接填入类名(如:Person.class)

 代码示例

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

public class TestMethod {

	public static void main(String[] args) throws Exception{
		
		//1.创建Class类的实例
		Class<Person> clazz = Person.class;
		
		//2.获取构造器
		Constructor<Person> person =  clazz.getDeclaredConstructor();
		
		//3.创建对象
		Person p1 = person.newInstance();
		
		//4.获取方法
		Method method =  clazz.getMethod("output");
		
		//5.调用方法
		Object obj =  method.invoke(Person.class);//无需填入对象
		
		//6.打印返回值【可有可无】
		System.out.println(obj);
		
	}
}

效果截图

 2.2 调用非public的方法

说明:

        与获取属性、方法相似。

  1. 需要使用getDeclaredMethod()方法     
  2. 需要使用setAccessible(true),设置成可以访问  

代码示例

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

public class TestMethod {

	public static void main(String[] args) throws Exception{
		
		//1.创建Class类的实例
		Class<Person> clazz = Person.class;
		
		//2.获取构造器
		Constructor<Person> person =  clazz.getDeclaredConstructor();
		
		//3.创建对象
		Person p1 = person.newInstance();
		
		//4.获取方法
		Method method =  clazz.getDeclaredMethod("shadow");//私有方法
		
		//5.设置方法可访问
		method.setAccessible(true);
		
		//5.调用方法
		Object obj =  method.invoke(p1);
		
		//6.打印返回值【可有可无】
		System.out.println(obj);
		
	}
}

 效果截图

 3.使用构造器

构造器:一般分为有参构造器无参构造器

3.1 无参构造器

之前很多代码,都是采用这种方式,这里简单略过

Class<Person> clazz = Person.class;
		
Constructor<Person> person =  clazz.getDeclaredConstructor();
		

3.2 有参构造器

如何创建?

  1. 在getDeclaredConstructor()填入参数即可,如:String.class
  2. 通过此构造器创建对象是,newInstance()里也要填入相应的参数,如:"张三"

代码示例

import java.lang.reflect.Constructor;

public class TestConstructor {

	public static void main(String[] args) throws Exception {
		
		Class<Person> clazz = Person.class;
		
		Constructor<Person> person =  clazz.getDeclaredConstructor(String.class,int.class);//填入你要使用的构造器的参数
		
		//创建对象
		Person p1 =  person.newInstance("张三",10);
		
		System.out.println(p1);
		
	}
}

效果截图

 4.GitHub已上传代码

点击链接,可以下载代码获取代码,感受一下Java中的反射

gitee网站也上传了代码:点击链接,获取代码