java反射机制详解

反射

动态语言

动态语言是一类在运行时就可以改变其结构的语言:例如新的函数,对象,甚至代码都可以被引用,已有函数可以被删除或是其他结构上的变化。通俗的说就是在运行是代码可以根据某些条件改变自身结构。

反射概念

Reflection(反射)是Java被是为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

Class c = Class.forName(“java.lang.String”)

加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了完整的类的信息。我们可以通过这个对象看到类的结构。这个对象就想一个镜子,透过这个镜子,看到类的结构,所以,我们形象的称之为:反射

正常方式:

graph LR
引用需要的'包类'名称-->通过new实例化
通过new实例化-->获取实例化对象

反射方式:

graph LR
实例化对象--> getclass方法
getclass方法-->得到完整的'包类'名称

反射机制提供的功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时获取泛型信息
  • 在运行是调用任意一个对象的成员变量和方法
  • 在运行时处理注解
  • 生成动态代理

发射的优点和缺点

优点

可以实现动态创建对象和编译,体现出很大的灵活性

缺点

对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且他需要满足我们什么要求。这种操作总是鳗鱼直接执行相同的操作。

class类

在Object类中定义了一下的方法,此方法将被所有子类继承

public final Class getClass()

该方法返回值的类型是一个Class类,此类是Java反射的源头,实际上所谓反射从程序的运行结果来看也是很好理解的,即:可以通过对象那个反射求出类的名称。

对象照镜子后得到的信息:某个类的属性,方法和构造器,某个类到底实现了那些接口。对于某个类而言,jre都为其保留一个不变的Class类型的对象。一个Class对象包含了特定某个结构的有关信息。

有关Class类的介绍
  • Class本身也是一个类
  • Class对象只能由系统创建对象
  • 一个加载的类在jvm中只会有一个Class实例
  • 一个Class对象对性的是一个加载道JVM中的class文件
  • 每个类的实例都会记得自己是由那个Class实例所生成
  • 通过Class可以完整的得到一个类的所有被加载的结构
  • Class类是Reflection 的根源,针对任何你想动态加载,运行的类,唯有先获取相应的Class对象
方法名功能说明
Static ClassforName(String name)返回指定类名name的Class对象
Object newlnstance()调用缺省构造函数,返回Class对象的一个实例
getName()返回此Class对象所表示的实体(类,接口,数组类或void)的名称
Class getSuperClass()返回当前Class对象的父类的Class对象
Class[] getinterfaces()获取当前Class对象的接口
ClassLoader getConstructors()返回一个包含某些Constructor对象的数组
Method getMothed(String name, class…T)返回一个Method 对象,此对象的形参类型为paramType
Field[] getDeclaredFields返回Field对象的一个数组
获取Class的方法
 public static void main(String[] args) throws ClassNotFoundException{
     Person person = new Student();
     System.out.println("这个人是"+person.name);
     
     //方式一:通过对象获得
     Class c1 = person.getClass();
     System.out.println(c1.hashCode());
     
     
     //方式二: forname获得
     Class c2 = Class.forName("包名.类名");
     
     //方式三:通过类名.class获取
      Class c3 = Student.class;
     
     //方式四:基本内置类型的包装类都有一个Type属性
     Class c4 = Integer.TYPE;
     
     //获取父类的类型
     Class c5 = c1.getSuperclass();
     
     
     class person{...}
     class Student{...}
 }    
  

类的加载过程

当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对类进行初始化

graph LR
类的加载'Load'-->类的链接'Link'
类的链接'Link'-->类的初始化'Initialize'

类的加载:将类的class文件读入内存,将静态数据转换为方法区的运行时数据结构,并为之创建一个java.lang.Class 对象。此对象由类加载器完成
类的链接:将类的二进制数据并到JRE中
类的初始化:JVM负责对类进行初始化

newInstance()方法于new关键词的区别

A.

  • new 是一个关键字,可以说是一个指令;
  • newInstance()是一个方法,Class对象的一个方法

B.

  • new主要作用时在内存中生成一个实例,而这个类可以没有提前加载到内存中
  • newInstance()主要是在内存中生成一个实例,而这个方法在使用前必须保证:a.这个类被加载到内存中,b.这个类已经被连接,而完成以上两个过程的是Class.forName()方法。

C.

  • new关键词的使用一般比较呆板的写入到程序中;
  • newInstance()方法一般用于框架,工厂模式等等。

D.

  • new关键字可以调用类的有参public构造方法
  • newinstance()方法只能调用类的无参构造方法。

java中Class.getMethod方法

Method Class.getMethod(String name,Class<?>…parameterTypes)

它的作用是是获取对象所声明的公开方法,方法的第一个方法是要获取方法的名字,第二个参数parameterTypes是按声明顺序表示该方法形参类型.

如: person.getClass().getMethod("speak",null);
//获取的是person对象的Speak方法,因为Speak方法没有形参,所以parmeterTypes 为null
person.getClass().getMethod("run",String.class);
//获取person对象的run方法的参数是String类型的,所以parameterTypes为String.class

setMethod.invoke()方法

invoke(Object obj,Objecat…args)

invoke方法 的参数,第一个是Object类型也就是调用`该方法的对象
第二个参数是一个可变参数类型,这个可变类型怎么能传递给一个数组类型呢?一个是多个参数.一个是一个数组参数,显然参数的个数不匹配

怎么解决呢?

解决的办法就是将可变参数变为一个参数:

1.将传递进去的S转化为Object类型
2.将S重新包装为一个object数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java反射机制是指在运行时动态地获取一个类的信息,并可以操作类的属性、方法和构造器等。Java反射机制可以使程序员在运行时动态地调用类的方法和属性,扩展类的功能,并可以实现注解、工厂模式以及框架开发等。 Java反射机制的原理如下:首先,Java编译器将Java源代码编译为字节码文件,字节码文件包含着类的信息,这些信息包括类的名称、方法、属性和构造器等等。接着,Java虚拟机将字节码文件加载到内存,然后通过类加载器将类加载到内存形成一个类对象,这个类对象可以操作字节码文件的信息。 使用Java反射机制的过程如下:首先获取类对象,通过类对象来获取类的构造器、属性、方法等信息,然后调用构造器来创建对象,通过属性获取和设置类的成员属性,通过方法调用类的方法等。 Java反射机制的优点是可以在运行时动态地得到类的信息,使得程序员在程序运行时能够对类进行更加灵活的操作,并可以使得程序更加通用化,同时也存在着一定的性能问题,因为Java反射机制需要Java虚拟机进行一定的额外处理,所以在程序运行时需要进行额外的时间和资源消耗。 总之,Java反射机制Java语言的一项重要特性,在Java开发广泛应用,在代码编写、框架开发以及API开发具有重要作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值