java 反射Reflect

本文深入探讨Java反射机制的使用方法,包括如何加载类、获取类的方法和属性、创建对象、调用方法等。同时介绍了如何通过反射操作数组、构造器等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class ReflectDemo {

public static void main(String[] args) throws ClassNotFoundException,
SecurityException, IllegalArgumentException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException,
InstantiationException, NoSuchFieldException {
Class claz = Class.forName("com.yss.test.reflect.Demo");// 载入指定的类 or
// Demo.class;
/**
* 获取该类及继承类中的方法
*/
Method[] methods = claz.getMethods();// 包括继承而来的所有的public方法名
for (int index = 0; index < methods.length; index++) {
// 获取该方法的名字
System.out.println(methods[index].getName());
// 获取该方法的所有参数类型
Class[] pvec = methods[index].getParameterTypes();
for (int i = 0; i < pvec.length; i++) {
System.out.println(pvec[i]);
}
// 获取该方法的所有异常类型
Class[] exce = methods[index].getExceptionTypes();
// 该方法的返回值类型
System.out.println(methods[index].getReturnType());
// 判断该方法定义在那个类中
System.out.println(methods[index].getDeclaringClass());
}

Field[] fields = claz.getFields();// 包括继承而来的所有public方法名
for (int index = 0; index < fields.length; index++) {
System.out.println(fields[index].getType() + " "
+ fields[index].getName());
}

System.out.println("-------------------------");
/**
* 获取当前类中的属性和方法
*/
Method[] methodss = claz.getDeclaredMethods();// 只在该类中定义的(不包含继承而来的)共有\
// 私有的方法名
for (int index = 0; index < methodss.length; index++) {
System.out.println(methodss[index].getName());
}
Field[] fieldss = claz.getDeclaredFields();// 只有该类下定义的(不包含继承来的)共有、私有的属性名
for (int index = 0; index < fieldss.length; index++) {
System.out.println(fieldss[index].getType() + " "
+ fieldss[index].getName());
/**
* 用来描述字段成员的修饰语,如“private int”。这些修饰语自身由整数描述,而且使用 Modifier.toString
* 来返回以“官方”顺序排列的字符串描述 (如“static”在“final”之前)。这个程序的输出是:
*/
System.out
.println(Modifier.toString(fieldss[index].getModifiers()));
}
/**
* 判断new的对象是否是claz的实例
*/
boolean ifflag = claz.isInstance(new Demo());
boolean ifflags = claz.isInstance(new SDemo());
System.out.println(ifflag + " " + ifflags);// true 和 false

/**
* 获取当前方法的构造函数
*/
Constructor[] cons = claz.getDeclaredConstructors();
for (int con = 0; con < cons.length; con++) {
System.out.println("获取构造方法: " + cons[con].getName());
}
test_method_invoke(claz);

invoke_constructor(claz);

change_fields(claz);

create_array();

create_complex_arr();
}

/**
* @param claz
* @throws SecurityException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
*
* 利用反射 根据方法的名称来执行方法
*/
public static void test_method_invoke(Class claz) throws SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
InstantiationException {
Class[] params = new Class[2];// 设置参数类型
params[0] = int.class;
params[1] = Integer.TYPE;

Object demo = claz.newInstance();
Object[] cp = new Object[2];// 具体参数
cp[0] = new Integer(11);
cp[1] = new Integer(3);

Method params_method = claz.getMethod("share", params);// 获取有参share方法
Method no_params_method = claz.getMethod("share");// 获取无参share方法

Object obj = params_method.invoke(demo, cp);
no_params_method.invoke(demo);

Integer intg = (Integer) obj;
System.out.println("返回值: " + intg.intValue());
}

/**
* 调用constructor的实例
*
* @param claz
* @throws IllegalAccessException
* @throws InstantiationException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws SecurityException
*/
public static void invoke_constructor(Class claz)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
SecurityException, NoSuchMethodException {
Class[] params = new Class[4];// 设置参数类型
params[0] = int.class;
params[1] = Long.TYPE;
params[2] = String.class;
params[3] = Double.TYPE;

Object demo = claz.newInstance();
Object[] cp = new Object[4];// 具体参数
cp[0] = new Integer(11);
cp[1] = new Long(20);
cp[2] = new String("青龙");
cp[3] = new Double(29);

Constructor constructors = claz.getConstructor(params);// 获取有参构造方法

Object obj = constructors.newInstance(cp);
}

public static void change_fields(Class claz) throws SecurityException,
NoSuchFieldException, InstantiationException,
IllegalAccessException {
Field field = claz.getField("sname");
Object obj = claz.newInstance();
System.out.println("设置前:" + ((Demo) obj).getSname());
field.set(obj, "qinglong");
System.out.println("设置后:" + ((Demo) obj).getSname());
}

/**
* 数组在 Java 语言中是一种特殊的类类型,一个数组的引用可以赋给 Object 引用
*
* 创建了 n个单位长度的 String 数组,为第 n个位置的字符串赋了值
*
* @throws ClassNotFoundException
*/
public static void create_array() throws ClassNotFoundException {
Class claz = Class.forName("java.lang.String");
Object objarr = Array.newInstance(claz, 4);
Array.set(objarr, 2, "qing");
System.out.println("创建数组:" + Array.get(objarr, 2));
}

/**
* 创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为
* 37。注意,多维数组实际上就是数组的数组,例如,第一个 Array.get 之后,arrobj 是一个 10 x 15
* 的数组。进而取得其中的一个元素,即长度为 15 的数组,并使用 Array.setInt 为它的第 10 个元素赋值。
* 注意创建数组时的类型是动态的,在编译时并不知道其类型。
*/
public static void create_complex_arr() {
int dims[] = new int[] { 5, 10, 15 };
System.out.println(dims[2]);
Object arr = Array.newInstance(Integer.TYPE, dims);
Object arrobj = Array.get(arr, 3);
Class cls = arrobj.getClass().getComponentType();
System.out.println(cls);
arrobj = Array.get(arrobj, 5);
Array.setInt(arrobj, 10, 37);
int arrcast[][][] = (int[][][]) arr;
System.out.println(arrcast[3][5][10]);

}
}

class SDemo {
private String aa;
public int bb;
public String sname;

public SDemo() {
// System.out.println("父类的构造方法");
}

public SDemo(String aa, int bb, String sname) {
this.aa = aa;
this.bb = bb;
this.sname = sname;
}

public void share() {
System.out.println("父类中的方法无参数");
}

public void share(int a, int b, int c) {
System.out.println("父类中的方法有参数");
}

public String getAa() {
return aa;
}

public void setAa(String aa) {
this.aa = aa;
}

public int getBb() {
return bb;
}

public void setBb(int bb) {
this.bb = bb;
}

public String getSname() {
return sname;
}

public void setSname(String sname) {
this.sname = sname;
}

}

class Demo extends SDemo {

public String name;
private int age;
private double score;
private long card;

public Demo(int age, long card, String name, double score) {
System.out.println("子类有参构造方法。。。。。");
this.age = age;
this.card = card;
this.name = name;
this.score = score;
}

public Demo() {
// System.out.println("子类构造方法");
}

public void share() {
System.out.println("子类中的方法无参数");
}

public int share(int a, int b) {
System.out.println("子类中的方法有参数");
return a + b;
}

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 double getScore() {
return score;
}

public void setScore(double score) {
this.score = score;
}

public long getCard() {
return card;
}

public void setCard(long card) {
this.card = card;
}
}

参照链接:http://www.iteye.com/topic/602805
### Java 反射 Reflect 使用教程 #### 获取 `Class` 对象 在Java中,反射的核心是`Class`对象。可以通过三种方式获得: - **通过类名**:使用`.class`语法。 ```java Class<?> clazz = String.class; ``` - **通过实例**:调用对象的`.getClass()`方法。 ```java Object obj = new Integer(0); Class<?> clazz = obj.getClass(); ``` - **通过全限定名**:利用`Class.forName(String className)`静态方法。 ```java try { Class<?> clazz = Class.forName("java.lang.String"); } catch (ClassNotFoundException e) { // Handle exception } ``` 上述每种方法都可用于获取指定类型的`Class`对象[^1]。 #### 访问字段 (`Field`) 一旦有了`Class`对象,就可以访问其声明的成员变量(即字段)。这包括私有字段在内的所有字段。 ```java // 假设有一个Person类 public class Person { private String name; public void setName(String n){ this.name=n; } @Override public String toString(){ return "Name:"+this.name; } } try { Class<Person> personClass = Person.class; // 获取名为"name"的私有字段 Field field = personClass.getDeclaredField("name"); // 设置可访问标志位为true以便能够读写该字段 field.setAccessible(true); Person p = new Person(); // 向p设置值 field.set(p,"John Doe"); System.out.println(p.toString()); // 输出 Name:John Doe } catch (NoSuchFieldException | IllegalAccessException e) { // 处理异常... } ``` 这段代码展示了如何创建一个新的人(`Person`)对象并为其内部不可见的名字(`name`)属性赋值。 #### 调用方法 (`Method`) 除了可以操作字段外,还可以通过反射来执行某个特定的方法。 ```java try { Class<Person> personClass = Person.class; Method method = personClass.getMethod("setName",String.class); Person p = new Person(); // 执行setName()方法并将参数传递给它 method.invoke(p, "Jane Doe"); System.out.println(p.toString()); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // 处理异常... } ``` 这里说明了怎样找到公共方法`setName`并通过传入的对象实例去调用这个方法。 #### 构造器 (`Constructor`) 最后,也可以借助于反射机制来进行对象的构建工作。 ```java try { Class<Person> personClass = Person.class; Constructor<Person> constructor = personClass.getConstructor(); Person p = constructor.newInstance(); System.out.println(p.toString()); } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // 处理异常... } ``` 此片段显示了一个无参构造函数是如何被用来生成新的`Person`实体的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值