反射反射程序员的快乐——精解Java反射的使用

能够分析类能力的程序称为反射,反射机制的功能十分强大

Class类是什么

在java中万物皆对象,“在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息(*指运行时的类型标识)跟踪着每个对象所属的类。虚拟机利用运行时类型标识信息选择相应的方法执行。
然而,可以通过专门的Java类访问这些信息(这些运行时的类型标识)。保存这些信息的类被称为Class。

以上引号内的内容来自于Java核心技术规范卷1,190页。我个人对这段通俗的理解

public class dog
{
  private String name;
  public dog(){}
  public dog(String name)
  {
   this.name=name;
  }
  public  void myName()
  {
   System.out.println("汪汪,我叫"+this.name);
  }
}
public class cat
{
  private String name;
  public cat(){}
  public cat(String name)
  {
   this.name=name;
  }
  public  void myName()
  {
   System.out.println("喵喵 ,我叫"+this.name);
  }
}
public class Test
{
 public static void main(String[]  args)
 {
  dog d=new dog("小狗");
  cat c=new cat("小猫");
  d.myNmae();
  c.myNmae(); 
 }
}

这两个类的实例d和c同时去调用myName()方法时,显而易见的输出是不同的,在Java虚拟机类是如何判断 d.myNmae()和 c.myNmae()的呢? “Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识”显然d和c都有各自的类型标识来相互区别d,c究竟是来着与哪些类的实例。**每个对象都需要一个类型标识,所以在虚拟机中每个类(,java文件)都对应一个Class类(.class)。**例如dog.java在虚拟机中会生成一个dog.class。这个dog.class会记录dog类的所有信息,当然也包括它生成对象的类型标识。

class类可以做什么?怎么得到?

既然既然类.class记录了这个类的所有信息,我们当然可以用它来为所欲为啦。我们可以用它调用这个类的属性、构造方法、方法,当然前提是先得到这个类的Class类。

如何得到Class类

三种方法

dog d;
Class c1=d.getClass();//通过类的实例调用getClass()方法去获得Class类对象

Class c2=dog.class;//类.class获得Class类对象

String className="包名.dog"//可以通过选中类文件--右键--Copy Qualified Name得到
Class c3=Class.forName(className);//调用静态方法forName()获得类名对应的Class对象

用Class类做什么?

获取类的实例

String className="包名.dog"//可以通过选中类文件--右键--Copy Qualified Name得到
Class c3=Class.forName(className);//调用静态方法forName()获得类名对应的Class对象
Object dd=c3.newInstance();//得到了dog类的一个实例
(dog)dd;

获取类的名字

String name=c3.getName();

获取类的构造方法

Constructor[] ct1=c3.getConstructors();//Constructor对象的数组,包含了Class对象所描述类的所有公有构造函数,这里的所描述类就是dog类。
Constructor[] ct2=c3.getDeclaredConstructors();//Constructor对象的数组,包含了Class对象所描述类的所有构造函数。
/*
返回数组中的元素没有排序,也没有任何特定的顺序,这样的描述同时存在于getDeclaredFields()方法和getDeclaredMethods()中。我又向Person类中加入了若干构造方法,发现分别在第3,6,13,15,27次时,输出顺序全部发生改变。由此可以得出结论:
① 在取得全部构造方法,普通方法和属性的时候,返回数组里元素的位置是完全随机的。
② 这种随机指的不是每次执行返回的结果不同,而是随着方法和属性的增加而改变返回顺序。
所以不要采用getConstructors()方法,用数组下标获取构造方法的方式初始化对象,以免以后在类中新增构造方法时出现异常。
可以采用较为安全的getConstrutor()方法指定参数类型,再通过newInstance()方法为对象初始化:
版权声明:本文为CSDN博主「MaYuKang」的原创文章,
原文链接:https://blog.csdn.net/MaYuKang/article/details/86660418*/

//getConstructors(Class<?>...parameterTypes)返回带参数类型的构造函数
Constructor ct3=c3.getConstructors(string.class);//这样就返回了dog类的有参构造函数

有了构造方法,当然可以用构造方法去实例化一个对象

Constructor ct3=c3.getConstructors(string.class);//这样就返回了dog类的有参构造函数
Object ob=ct3.newInstance("小狗");

获取类的成员

Field[] fields=c3.getFields();//取得所有公有属性(包括父类继承)
Field[] fields=c3.getDeclaredFields();//取得所有属性

Field name=c3.getFields("name");//获取指定的成员
Field name=c3.getDeclaredFields("name");

获取类的成员方法

Method[] md=c3.getMethods();//获取公有成员方法
Method[] md=c3.getDeclaredMethods();//获取所有成员方法

Method md=c3.getMethods(String name,Class<?>...parameterTypes);//获取指定公有成员方法
Method md=c3.getDeclaredMethods(String name,Class<?>...parameterTypes);

Method m=c3.getMethods("myName",string.class);//获取dog类中的myName方法;
m.invoke(dog,"小狗");//执行成员方法,返回类型是Object;

实战Java用反射+配置文件结合抽象工厂模式实现数据库访问程序

Java核心技术规范卷1对Field、Method 和 Constructor 的描述

在 java.lang.reflect 包中有三个类 Field、Method 和 Constructor 分别用于描述类的域、方法和构造器。这三个类都有一个叫做 getName的方法,用来返回项目的名称Field 类有一个 getType方法,用来返回描述域所属类型的 Class对象。Method 和 Constructor 类有能够报告参数类型的方法,Method 类还有一个可以报告返回类型的方法。这 三个类还有一个叫做 getModifiers的方法,它将返回一个整型数值,用不同的位开关描述 public 和 static 这样的修饰符使用状况。另外,还可以利用java.lang.refleCt 包中的 Modifiei•类的静态方法分析getModifiers返回的整型数值。例如,可以使用 Modifier 类中的 isPublic、isPrivate或 isFinal 判断方法或构造器是否是 public、private或 final。我们需要做的全部工作就是调用 Modifier 类的相应方法,并对返回的整型数值进行分析,另外,还可以利用 Modifier.toS tring方法将修饰符打印出来。
Class类中的 getFields、getMethods和getConstructors方 法 将 分 别 返 回 类 提 供 的public域、方法和构造器数组,其中包括超类的公有成员。Class类的 getDeclareFields、getDeclareMethods和 getDeclaredConstructors方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超类的成员。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值