JAVA学习日记:反射机制(4)

反射机制学习日记(4)

今天是第四课:
主要内容:

	如何运用反射机制创建一个对象
	调用对象方法
	访问对象属性并设置

如何运用反射机制创建一个对象:

	调用无参构造方法进行对象的创建:
		使用Class类的newInstance()方法
		处理两个必要的异常:InstantiationException、IllegalAccessException
	调用指定参数类型的构造方法进行对象的创建:
		使用Constructor类的newInstance()方法

如何调用对象方法:

		Object invoke(Object obj, Object...args)方法
		第一个参数:
			被Method实例对象封装的方法的本类
		第二个参数:
			它代表的这个要调用的方法的参数列表
		具体使用情况在代码里会详细介绍

如何访问对象属性并设置值:

		使用Field的get()方法或getXXX()方法获取属性;
		使用Field的set()方法设置属性;
		可以通过设置setAccessible(true)方法后,调用、或访问对象的私有属性;

代码环节:
ObjectMakerDemo类(测试以上功能的类):

package LessonForReflection04;

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

/*
 * 	如何运用反射机制创建一个对象
 * 
 * 		调用无参构造方法进行对象的创建
 * 			使用Class的newInstance()方法
 * 			处理两个必要的异常:InstantiationException、IllegalAccessException
 * 
 * 		调用指定参数类型的构造方法进行对象的创建
 * 			使用Constructor类的newInstance()方法
 */

public class ObjectMakerDemo 
{
     
	public static void main(String args[])
	{
     
		//使用默认构造方法进行创建
		try 
		{
     	
			Class<Rectangle> c1 = Rectangle.class;
			Rectangle recObj1 = c1.newInstance();
			
			
			
			Class<?> c2 = Class.forName("LessonForReflection04.Rectangle");
			Rectangle recObj2 = (Rectangle)c2.newInstance();
			
		} catch (InstantiationException | ClassNotFoundException | IllegalAccessException e)
			{
     
				e.printStackTrace();
			}
		
		System.out.println("-------------------------------------------");
		
		//使用指定构造方法进行创建
		Class<Rectangle> c3 = Rectangle.class;
		Rectangle recObj3 = new Rectangle();
		
		try 
		{
     
			Constructor cons1 = c3.getConstructor(String.class);
			recObj3 = (Rectangle)cons1.newInstance("Black");//对应c3.getConstructor(String.class);
			
			Constructor cons2 = c3.getConstructor(double.class, String.class);
			Rectangle recObj4 = (Rectangle)cons2.newInstance(2.2, "Pink");
		} catch (NoSuchMethodException | SecurityException | InstantiationException | 
				IllegalAccessException | IllegalArgumentException | InvocationTargetException e) 
			{
     
				e.printStackTrace();
			}
		
		System.out.println("-------------------------------------------");
		//调用对象的实例方法
		
		try 
		{
     
			//1.
			//调用不带参数的业务方法
			System.out.println("调用不带参数的业务方法");
			Method m1 = c3.getDeclaredMethod("showAll");
			//showALL()这个方法被我们的Method类封装成了一个对象
			System.out.println(m1.invoke(recObj3));//这里打印的是showAll()方法的返回值,这里是void类型的返回值,所以是null
			/*
			 * Object invoke(Object obj, Object...args);
			 * 	第一个参数为:
			 * 		被Method实例对象封装的方法的本类
			 * 		拿上面的例子来说就是:m1是Method类的对象,m1封装了
			 * 		Class类把Rectangle类封装而来的c3这个对象运用getDeclaredMethod指定方法得到的Rectangle里的void showAll()方法
			 * 
			 * 	第二个参数是可变长度参数:
			 * 		它代表这个要调用的方法的参数列表,
			 * 		此例子中的showAll()方法
			 */
			
			//2.
			//调用带参数的业务方法
			System.out.println("调用带参数的业务方法");
			Method m2 = c3.getDeclaredMethod("getArea", int.class, double.class);
			double area1 = (double)m2.invoke(recObj3, 4,5);
			System.out.println(area1);
			
			
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException |
				IllegalArgumentException | InvocationTargetException e) 
			{
     
				e.printStackTrace();
			}
		
		
		System.out.println("-------------------------------------------");
		//获取实例对象的属性值,然后设置值
			System.out.println("获取实例对象的属性值,然后设置值");
			try 
			{
     
				//步骤和上面得到方法并使用的过程很相似
				Field f1 = c3.getDeclaredField("color");
				f1.set(recObj3, "Black");//运用set方法设置值
				System.out.println(f1.get(recObj3));//运用get方法获得值
				
				
				Field f2 = c3.getDeclaredField("length");
				/*
				 * 	正常情况下想这样访问设置private属性的值是不可能的
				 * 		f2.set(recObj3, 3);
				 * 		System.out.println(f2.get(recObj3));
				 */
				
				//想要设置private属性的值用如下方法
				f2.setAccessible(true);
				f2.set(recObj3, 3);
				System.out.println(f2.get(recObj3));
				
			} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) 
				{
     
					e.printStackTrace();
				}
		
	}
}

Rectangle类(测试对象主要使用的类):

package LessonForReflection04;

public class Rectangle 
{
     
	private int length;//长
	protected double wide;//宽
	String color;//颜色
	
	//以下方法均为测试使用无实意
	public Rectangle(String color) 
	{
     
		super();
		this.color = color;
		System.out.println("--public Rectangle(String color)--");
	}
	
	public Rectangle(double wide, String color)
	{
     
		super();
		this.wide = wide;
		this.color = color;
		System.out.println("--public Rectangle(double wide, String color)--");
	}

	public Rectangle() 
	{
     
		System.out.println("--public Rectangle()--");
	}
	
	public void showAll()
	{
     
		System.out.println("--showAll() in Rectangle--");
	}
	
	public double getArea(int a, double b)
	{
     
		System.out.println("a * b = "+(a*b));
		return (a*b);
	}
	
	public String getColor(String s)
	{
     
		System.out.println("--getColor(String s) in Rectangle--");
		return s;
	}
}

部分文字来源于:
咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
轻量化研习Java相关技术倡导者
“爱码学院”联合创始人自适应教学理念提出者践行者;多年开发及项目管理经历;出版《JavaEE企业级应用与开发》一书;10余年高校项目实践毕设指导经验;企业软培经验丰富。

2020.10.06

你可能感兴趣的:(JAVA学习,java,反射,编程语言)