黑马程序员—反射

 反射的基石——Class类

java程序中各个java类属于同一类事物,描述这类事物的java类名就是Class


1、Class类代表java类,对应各个类在内存中存在的字节码,例如Person类的字节码,ArrayList类的字节码等等。

2、一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码

是不同的,所以它们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象具有相同的

类型,这就是Class。

3、如何得到各个字节码对应的实例对象呢(Class类型)?

1)类名.class 。例如System.class

2)对象.getClass()。例如 new Date().getClass()

3)Class.forName("类名")。例如Class.forName("java.util.ArrayList") //反射的时候常用到这种方法

4)九个预定义的Class实例对象

8个基本数据类型和void

总结:只要在程序中出现的类型,都有各自的Class实例对象


反射的定义:反射就是把java类中的各种成分映射成相应的java类!

下面将介绍java程序中不同部分的反射。


Constructor类

1、得到某个类所有的构造方法

Constructor[] constructors = Class.forName("java.lang.String").getConstructors();

2、得到某个具体的构造方法

Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class); //获得指定的构造方法时需要用到参数类型

3、创建实例对象

通常方式:String s1 = new String(new StringBuffer("abc"));

反射方式:String s1 = (String)Class.forName("java.lang.String").getConstructor(StringBuffer.class).newInstance(new StringBuffer("abc"));

//调用获得对象的方法时需要用到前面指定参数的实例对象作为参数,如上句红字所示。




Field类

代表某个类中的一个成员变量,提供有关类或接口的单个字段信息,当一个类中的某个成员变量时private的时候,可用暴力反射的手段进行获取。

下面用一个FieldPoint类来进行举例,如下图所示

ReflectPoint pt1 = new ReflectPoint(3,5);


Field fieldY = pt1.getClass().getField("y"); //获取参数y的反射

int y = fieldY.get(pt1); //获取在pt1对象中y的具体值,fieldY不是对象身上的变量,而是类上,要用它去取具体某个对象身上的值

由于x是私有参数,所以要用暴力手段去进行反射

Field fieldX = pt1.getClass().getDeclaredField("x"); //只要是已经声明过的都可以获取

fieldX.setAccessible(true);//设置权限为可访问的

System.out.println(fieldX.get(pt1));


练习:将任意一个对象中所有的String类型的成员所对象的字符串内容中的"b"改成"a"。




Method类

得到类中的一个方法。

例子:得到String中的charAt(int x)方法

Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);//getMethod方法的参数为(方法名,方法的参数)

charAt.invoke("abc",1); //使用这个方法,用invoke()


如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法。

下面演示一个类中用反射调用另一个类中的main方法:



数组的反射



HashCode的作用

1、在Hash集合中,每个对象都会有一个hashcode,每个对象根据自身的哈希码被分配到集合中的不同区域中,当存入新的对象时,只需根据这个

新对象的hashcode去其相对应的区域找有无相同的存在即可,提高了效率。

2、判断两个对象是否equals,也必须判断它们的hashcode。

3、当一个对象被存储进HashSet集合中后,就不能修改这个对象中参与计算hashcode的那些字段了,否则,修改后的对象与修改前的对象哈希值

就会不同,系统就会把修改前后的对象当成2个不同的对象,导致检索失败。更严重的会导致无法从HashSet中单独删除当前对象,从而造成内存泄露。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值