Java反射机制的使用

本文深入探讨了Java反射机制的使用方法,包括如何通过反射获取类成员、构造方法及调用私有成员等内容,并提供了实例演示。

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

AmigoEditText reflectEditTextFromAmigoSearchView(){
    	AmigoEditText amigoEditText = null;
        if(mAmigoSearchView != null){
        	
            Class<AmigoSearchView> amigoSearchViewClass = (Class<AmigoSearchView> )mAmigoSearchView.getClass();
//            Class superClass = amigoSearchViewClass.getSuperclass();
            
             if(amigoSearchViewClass != null){
            	 try {
//                Field field = superClass.getDeclaredField("mSearchSrcTextView");
            		 Field field = amigoSearchViewClass.getDeclaredField("mQueryTextView");
                field.setAccessible(true);
                Object obj = field.get(mAmigoSearchView);
                if(obj instanceof AmigoEditText){
                    amigoEditText = (AmigoEditText)obj;
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
                Log.e("AgendaActivity", "no such filed name mSearchSrcTextView in AmigoSearchView");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                Log.e("AgendaActivity", "can not access the field of mAmigoSearchView");
            }
        }
             }
            
        return amigoEditText;
    }

注意事项:

1.getField(String)和getDeclaredField的区别

getField(String)只是能获取你有权限获取的;而getDeclaredField可以获取任何权限的Field。

2.getDeclaredField也不能获取父类的成员。需要通过clazz.getSuperClass()去获取其父类,这个返回的父类类对象是代表他所有父类,通过这个Class对象,可以获取

  clazz的所有直接父类的成员,但是不能获取父类的父类的成员,需要进一步下去才可以。

3.getDeclaredFields()可以获取对应Class的所有成员

4.当没有该成员会抛出异常,或者父类为借口时,会返回null。

5.使用field时,如果该field为private,则需要需要field.setAccessible(true);


类的动态加载:

try {
        Class<?> clazz = Class.forName("com.mediatek.dcfdecoder.DcfDecoder");
        Object dcfDecoder = clazz.newInstance();
        
		Method method = clazz.getDeclaredMethod("forceDecryptFile", String.class,int.class);
		return (byte[])(method.invoke(dcfDecoder, filePath, consume));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

try {
          Class<?> clazz = Class.forName("com.mediatek.common.MPlugin");
  		Method method = clazz.getDeclaredMethod("createInstance", String.class,Context.class);
  		sImageOptions  = (IImageOptionsExt)(method.invoke(null, IImageOptionsExt.class.getName(), context.getApplicationContext()));
  		} catch (Exception e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}

这样做的用处是,编译环境没有这个类,而运行环境中有这个类。这样编译就不会检查。

如果调用的是静态方法,invoke()方法的第一个参数为null即可。

实例化使用newinstance(),会调用该类的无参构造函数,且该函数必须是可访问的。

如果需要调用有参的构造函数,可以使用反射调用Constructor,这样还可以调用私有构造方法

在获取Method时,若方法参数是基本类型(如:int,boolean),就传入int.class或者Integer.TYPE

如下代码展示了如何使用反射构造方法去实例化一个

Class cls=Class.forName("test.reflect.A");  //import class
Constructor cst=cls.getConstructor(new Class[]{String.class}); //get the constructor
Object obj=cst.newInstance(new Object[]{new String("invoke Construct method!")}); //get a new instance 





<think>我们正在讨论Java反射机制使用示例。根据用户需求,我们需要提供Java反射机制的示例代码,并解释其基本用法。参考提供的引用内容,特别是引用[4]中给出了一个通过反射获取对象属性键值的示例,我们可以以此为基础进行扩展。用户要求的是“java反射机制使用示例代码”,因此我们需要展示反射的几个常见用途:获取类信息、动态调用方法、访问属性等。根据引用[3]:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。下面我们将分步骤介绍反射的基本使用,并提供相应的示例代码。注意:反射操作可能会破坏封装性,且性能较低,应谨慎使用(引用[2]提到使用反射需要注意的事项)。步骤:1.获取Class对象2.获取类的属性(Field)3.获取类的方法(Method)4.获取类的构造器(Constructor)5.动态创建对象并调用方法示例代码将展示以上步骤。我们首先定义一个简单的Java类,用于后续反射操作。</think>### Java反射机制使用示例 Java反射机制允许在运行时动态操作类、方法和属性,下面通过几个典型示例说明其用法: #### 1. 获取类信息 ```java // 获取Class对象的三种方式 Class<?> cls1 = Class.forName("java.lang.String"); // 通过全限定名 Class<?> cls2 = String.class; // 通过.class语法 Class<?> cls3 = "Hello".getClass(); // 通过实例对象 // 输出类信息 System.out.println("类名: " + cls1.getName()); System.out.println("父类: " + cls1.getSuperclass().getName()); System.out.println("接口: " + Arrays.toString(cls1.getInterfaces())); ``` #### 2. 动态操作对象属性 ```java class Person { private String name; private int age; // 省略构造方法及getter/setter } public static void main(String[] args) throws Exception { Person person = new Person("张三", 25); // 获取所有声明的属性 Field[] fields = person.getClass().getDeclaredFields(); for (Field field : fields) { // 允许访问私有属性 field.setAccessible(true); String fieldName = field.getName(); Object value = field.get(person); System.out.printf("%s: %s\n", fieldName, value); } // 动态修改属性值 Field ageField = person.getClass().getDeclaredField("age"); ageField.setAccessible(true); ageField.set(person, 30); // 修改年龄 System.out.println("新年龄: " + person.getAge()); } ``` #### 3. 动态调用方法 ```java class Calculator { public int add(int a, int b) { return a + b; } private String formatResult(int result) { return "结果: " + result; } } public static void main(String[] args) throws Exception { Calculator calc = new Calculator(); Class<?> cls = calc.getClass(); // 调用公共方法 Method addMethod = cls.getMethod("add", int.class, int.class); int sum = (int) addMethod.invoke(calc, 5, 3); System.out.println("加法结果: " + sum); // 调用私有方法 Method formatMethod = cls.getDeclaredMethod("formatResult", int.class); formatMethod.setAccessible(true); String formatted = (String) formatMethod.invoke(calc, sum); System.out.println(formatted); } ``` #### 4. 动态创建对象 ```java // 通过无参构造创建实例 Class<?> stringClass = Class.forName("java.lang.String"); String str = (String) stringClass.getDeclaredConstructor().newInstance(); System.out.println("空字符串长度: " + str.length()); // 通过有参构造创建实例 Constructor<?> strConstructor = stringClass.getConstructor(String.class); String hello = (String) strConstructor.newInstance("Hello World"); System.out.println("创建字符串: " + hello); ``` ### 使用注意事项 1. **性能影响**:反射操作比直接调用慢$10-100$倍[^2],高频场景需谨慎 2. **安全限制**:反射可能绕过访问控制,需调用`setAccessible(true)`访问私有成员 3. **类型安全**:编译期类型检查失效,需自行确保类型正确性 4. **模块系统**:Java 9+模块系统中,需要`opens`声明才能访问非公共成员 > 反射打破了代码的封装性,但为框架开发(如Spring)、动态代理、序列化等场景提供了基础能力[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值