反射(二)---newInstance、get\set、invoke

Person

package com.harvic.blog_reflect_3;

import android.util.Log;

import java.util.ArrayList;

public class Person {

	private int age;
	private String name;

	public Person() {
	}

	private Person(int age, String name) {
		this.age = age;
		this.name = name;
	}

	private Person(Integer age, String name) {
		this.age = age;
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Boolean testInvoke(Integer age, String name) {
		Log.d("qijian", "得到参数age:" + age + "   name:" + name);
		return true;
	}

}

MyActivity

package com.harvic.blog_reflect_3;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import android.support.v4.app.Fragment;
import android.widget.PopupWindow;

public class MyActivity extends Activity {
	private String TAG = "qijian";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				try {
					newInstanceDemo();


					getFieldsDemo();

					fieldgetset();


					methodInvokeDemo();

				} catch (Exception e) {
					Log.e(TAG, e.getMessage());
				}
			}
		});
	}

	/**
	 * 2、通过反射获取实例
	 */
	public void newInstanceDemo() throws Exception {
		Class<?> clazz = Person.class;
		Constructor<?> constructor = clazz.getDeclaredConstructor(
				Integer.class, String.class);
		constructor.setAccessible(true);

		// 构造实例一
		Person person1 = (Person) constructor.newInstance(new Integer(30),
				new String("harvic"));
		Log.d(TAG, "构造的参数为:" + person1.getName() + "  " + person1.getAge());

		// 构造实例二
		Person person2 = (Person) constructor.newInstance(50, "qijian");
		Log.d(TAG, "构造的参数为:" + person2.getName() + "  " + person2.getAge());

		try {
			// 构造实例三
			Person person3 = (Person) constructor.newInstance();
			person3.setAge(30);
			person3.setName("qijian");
			Log.d(TAG, "构造的参数为:" + person3.getName() + "  " + person3.getAge());
		} catch (Exception e) {
			Log.e(TAG, e.getMessage());
		}
	}

	/**
	 * 4、获取属性名
	 */
	public void getFieldsDemo() throws Exception {
		Class<?> clazz = Person.class;
		// 1、枚举
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			Log.d(TAG, "枚举到的field:" + field.getName());
		}
		// 2、指定名称
		Field field = clazz.getDeclaredField("age");
		field.setAccessible(true);
		Log.d(TAG, "得到age对应的field:" + field.getName());

	}

	/**
	 * 5、获取或设置指定类对象中某变量的值时,可以使用Field中的get,set方法
	 */
	public void fieldgetset() throws Exception {
		Class<?> clazz = Person.class;
		Constructor<?> constructor = clazz.getConstructor();
		Person person = (Person) constructor.newInstance();

		// 示例1:get() set()函数
		Field fName = clazz.getDeclaredField("name");
		fName.setAccessible(true);
		fName.set(person, "qijian");
		String val = (String) fName.get(person);
		// 利用set设置
		Log.d(TAG, "fieldName:" + val + "   personName:" + person.getName());

		// 示例2:getInt()与setInt()
		Field fAge = clazz.getDeclaredField("age");
		fAge.setAccessible(true);
		fAge.setInt(person, 20);
		Log.d(TAG,
				"fieldAge:" + fAge.getInt(person) + "   personAge:"
						+ person.getAge());

		// 示例3:给声明为原始类型的变量使用get()、set()
		Field fAge2 = clazz.getDeclaredField("age");
		fAge2.setAccessible(true);
		fAge2.set(person, 30);
		Integer ageval = (Integer) fAge2.get(person);
		Log.d(TAG,
				"fieldAge:" + ageval.toString() + "   personAge:"
						+ person.getAge());

	}

	/**
	 * 7、Invoke函数无疑是Method类中最重要的方法,它的功能是用于执行Method对象所对应的函数
	 */
	public void methodInvokeDemo() throws Exception {
		Class<?> clazz = Person.class;
		Person person = new Person();
		Method method = clazz.getDeclaredMethod("testInvoke", Integer.class,
				String.class);

		method.setAccessible(true);
		Boolean result = (Boolean) method.invoke(person, 25, "I m harvic");
		Log.d(TAG, "执行结果:" + result);
	}

}


Java中的反射机制允许运行时获取类的信息以及操作对象实例,而`reflect.invoke()`是一个通过反射直接调用目标方法的功能。 ### Java Reflect 的 `invoke()` 方法简介 `invoke()` 方法是 `java.lang.reflect.Method` 类的一个静态方法,在 `Method` 对象上调用此方法可以动态地调用该方法所代表的类或接口的方法。这个功能非常强大,可以在运行时决定要调用的方法名称、参数及其返回值类型,并传递给实际的对象。 #### 参数说明: 1. **第一个参数** - 要调用方法的实例对象 (`Object instance`)。 2. **第个参数** - 方法所需的参数列表 (`Object[] args`)。数组中的每个元素对应于方法声明中的一个参数。 3. **第三个参数** - 可选的标志位,用于控制如何处理方法调用的异常 (`boolean throwException`)。默认为 `false` 表示忽略异常并抛出 `IllegalAccessException`;设置为 `true` 则会抛出任何捕获到的异常。 ### 使用例子 假设我们有一个简单的类 `ExampleClass`: ```java public class ExampleClass { public void exampleMethod(int x) { System.out.println("Received value: " + x); } } ``` 然后我们需要通过反射调用其 `exampleMethod` 方法: ```java import java.lang.reflect.Method; class ReflectionDemo { public static void main(String[] args) throws Exception { Class<?> clazz = ExampleClass.class; Method method = clazz.getMethod("exampleMethod", int.class); // 创建 ExampleClass 的实例 ExampleClass exampleInstance = new ExampleClass(); // 获取 Method 实例并调用它 Object result = method.invoke(exampleInstance, 42); // 输出结果 (尽管实际上这里的结果并没有被存储在变量里) System.out.println("Invoke result is: " + result); } } ``` 在这个例子中,`getMethod("exampleMethod", int.class)` 获取了 `exampleMethod` 方法的 `Method` 实例,并通过 `invoke` 方法调用了它,传入了一个整数作为参数。 ### 相关问题: 1. **反射和运行时灵活性之间的关系是什么?** 反射提供了一种在运行时查看和操纵类信息的能力,这极大地增加了程序的运行时灵活性,包括动态加载类、检查类属性和方法等。 2. **何时不应该使用反射?** 尽管反射功能强大,但在需要高效性能的场合下(如大规模数据处理或高并发应用),过度使用反射可能会导致性能下降。反射涉及到对字节码的解析和解释过程,相比于直接的指令执行,它的效率较低。 3. **如何优化使用反射以提高性能?** 尽量避免频繁使用反射,特别是在循环内或者需要大量调用的地方。考虑将反射的操作封装在初始化阶段完成,例如在构造函数或静态初始化块中预先获取所需的信息,而不是每次方法调用时都依赖反射。同时,使用原始类型而非包装类可以减少不必要的创建和销毁操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值