反射メカニズム学習日記(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
研究日記を転載できますが、出典を教えてください、ありがとうございます。