JAVA基础巩固加强 enhance day1反射 reflect

本文深入探讨了Java反射机制的基础概念、使用方法及其在实际应用中的综合实例,详细解析了Class类、Constructor类、Field类的功能及用法,并通过一个具体实例展示了如何利用反射更改对象中的String类型成员变量。

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

以前一直只知道有reflect这么一个类是用来反射的,听人家说java中的反射很难,晚上听罢张老师讲的反射这一节的内容,惶然大悟,原来反射就是把Java类中的各种成分映射成相应的java类。    
    反射的基础是要掌握Class这个类的,具体Class的类是干什么的,下面是api文档中的解释

    api中关于Class类的一段描述
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
翻译成中文
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。

    可以看出Class类就是一个类或者接口对象的一个实例在内存中的字节码,而如何得到一个类的字节码呢?其方法有三:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1         Class<? extends String> cls1 = str1.getClass();
2         Class<String> cls2 = String.class;
3         Class<?> cls3 = Class.forName("java.lang.String");

    而Class的isPrimitive()方法就是用来判断一个类的字节码是不是9个预定义的class
    
    接下来是Constructor类,Constructor类代表某个类中的一个构造方法。
   得到某个类所有的构造方法: 例子

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
  
    得到某一个构造方法:
   例子:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//获得方法时要用到类型
 
    创建实例对象:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->//通常方式:
String str = new String(new StringBuffer("abc"));
    
//反射方式: 
String str = (String)constructor.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象
   
    Class.newInstance()方法:
   例子:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->String obj = (String)Class.forName("java.lang.String").newInstance();
    该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
   该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。
   

下面是一个Field反射的综合实例
将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。 
首先定义一个ReflectPoint的类
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1 package com.anduo.day1;
 2 
 3 public class ReflectPoint {
 4     private int x;
 5     public int y;
 6     public String a = "ball";
 7     public String b = "basketball";
 8     public String c = "hello";
 9 
10     public ReflectPoint(int x, int y) {
11         super();
12         this.x = x;
13         this.y = y;
14     }
15 
16     @Override
17     public String toString() {
18         return "a=" + a + ";b=" + b + ";c=" + c;
19     }
20 }
21 

下面的步骤是:先从对象中得到所有为String类型的字段,2:得到Sting字段的值;3:用String类的replace方法代换a字符为b字符;4:把对象的String字段设置为修改完的新String。
齐活儿
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1 package com.anduo.day1;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Field;
 5 
 6 public class ReflectTest {
 7 
 8     
 9     public static void main(String[] args) throws Exception {
10 
11         
12         /**
13          * 成员变量的反射 Field
14          */
15         System.out.println("**成员变量的反射 Field**");
16         ReflectPoint pt1 = new ReflectPoint(1-1);
17         Field fieldY = pt1.getClass().getField("y");
18         // fieldY 不是对象身上的变量,而是类上,要用它来去对象上字段的值
19         System.out.println("p1 中  y = " + fieldY.get(pt1));
20         Field fieldX = pt1.getClass().getDeclaredField("x");// 获取私有属性字段
21         fieldX.setAccessible(true);// 暴力反射
22         System.out.println("p1 中  x = " + fieldX.get(pt1));
23 
24         /**
25          * 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
26          */
27         changeStringValue(pt1);
28         System.out.println(pt1);
29     }
30 
31     /**
32      * 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
33      * @param obj
34      * @throws IllegalArgumentException
35      * @throws IllegalAccessException
36      */
37     private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
38         Field[] fields = obj.getClass().getFields();
39         for (Field field : fields) {
40             // if(field.getType().equals(String.class))
41             if (field.getType() == String.class) {
42                 String oldValue = (String) field.get(obj);
43                 String newValue = oldValue.replace('a''b');
44                 field.set(obj, newValue);
45             }
46         }
47     }
48 
49 }
50 
结果如下
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->**成员变量的反射 Field**
p1 中  y 
= -1
p1 中  x 
= 1
a
=bbll;b=bbsketbbll;c=hello

综上可以看出,其实反射也没多难,人家那些写框架的也不就是用了些反射吗?把配置文件中的东西读出来,然后再调用下面的类去做应该做的事情,当然这个过程就用到了反射了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值