`
pingwei000
  • 浏览: 60918 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Java反射学习

阅读更多

所谓反射,可以理解为在运行时期获取对象类型信息的操作。传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码。严格地说,反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制,但是如果编程语言本身支持反射,那么反射的实现就会方便很多。

1,获得类型类
    我们知道在Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类。Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。例如,有如下一段代码:
A a = new A();
if(a.getClass()==A.class)
    System.out.println("equal");
else System.out.println("unequal");

    可以看到,对象a是A的一个实例,A某一个类,在if语句中使用a.getClass()返回的结果正是A的类型类,在Java中表示一个特定类型的类型类可以用“类型.class”的方式获得,因为a.getClass()获得是A的类型类,也就是A.class,因此上面的代码执行的结果就是打印出 “equal”。特别注意的是,类型类是一一对应的,父类的类型类和子类的类型类是不同的,因此,假设A是B的子类,那么如下的代码将得到 “unequal”的输出:
A a = new A();
if(a.getClass()==B.class)
    System.out.println("equal");
else System.out.println("unequal");

    因此,如果你知道一个实例,那么你可以通过实例的“getClass()”方法获得该对象的类型类,如果你知道一个类型,那么你可以使用“.class”的方法获得该类型的类型类。
 
2,获得类型的信息
    在获得类型类之后,你就可以调用其中的一些方法获得类型的信息了,主要的方法有:
getName():String:获得该类型的全称名称。
getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回null。
getInterfaces():Class[]:获得该类型实现的所有接口。
isArray():boolean:判断该类型是否是数组。
isEnum():boolean:判断该类型是否是枚举类型。
isInterface():boolean:判断该类型是否是接口。
isPrimitive():boolean:判断该类型是否是基本类型,即是否是int,boolean,double等等。
isAssignableFrom(Class cls):boolean:判断这个类型是否是类型cls的父(祖先)类或父(祖先)接口。
getComponentType():Class:如果该类型是一个数组,那么返回该数组的组件类型。
此外还可以进行类型转换这类的操作,主要方法有:
asSubclass(Class clazz):Class:将这个类型转换至clazz,如果可以转换,那么总是返回clazz这个引用,否则抛出异常。
cast(Object obj):Object:将obj强制转换为这个类型类代表的类型,不能转换的话将抛出异常。

    除了这些以外,利用类型类还可以反射该类型中的所有属性和方法。在Java中所有的属性信息都用Field表示,所有的方法信息都用Method表示,这辆各类都是java.lang.reflect包中的类。在Class中提供了4个相关的方法获得类型的属性:
getField(String name):Field
getFields():Field[]
getDeclaredField(String name):Field
getDeclaredFields():Field[]
其中getField用于返回一个指定名称的属性,但是这个属性必须是公有的,这个属性可以在父类中定义。如果是私有属性或者是保护属性,那么都会抛出异常提示找不到这个属性。getFields则是返回类型中的所有公有属性,所有的私有属性和保护属性都找不到。getDeclaredField获得在这个类型的声明中定义的指定名称的属性,这个属性必须是在这个类型的声明中定义,但可以使私有和保护的。getDeclaredFields获得在这个类型的声明中定义的所有属性,包括私有和保护的属性都会被返回,但是所有父类的属性都不会被返回。举个例子,先考虑下面两个类的声明:
class A extends B {
    public int a1;
    private int a2;
}
class B {
public int b1;
private int b2;
}
如果利用A的类型类调用getFields,那么会返回a1和b1两个属性,如果调用getField("a2")则会报错;如果调用getDeclaredFields则会返回a1和a2,如果调用getDeclaredField("b1")则会报错。

    对于方法也有类似的函数即:
getMethods():Method[]
getMethod(String name, Class ... parameterTypes):Method
getDeclaredMethods():Method[]
getDeclaredMethod(Strubg name, Class ...parameterTypes):Method
不定长参数...是JDK5.0以后新加入的语法。这几个方法的用法和上面的类似,只是在获得特定方法时,除了要告知方法的名字,还需要告知方法的参数,如果没有参数,那么可以传递null,或者空数组,但是最好的方法就是什么都不写,编译器会自行解决不定长参数问题。
    如果要获得所有的属性(方法),包括公有和私有的,那么就必须利用getDeclareFields(getDeclareMethods)方法,然后再利用getSuperClass的方法获得父类,然后递归下去。
 
3,属性和方法
    所有的属性都使用Field表示,所有的方法都使用Method表示。利用Field和Method可以获得属性和方法的信息,甚至执行是获取、修改属性值和调用方法。
 
    对于属性,主要有以下方法可以使用:
getType():Class:获得该属性的类型。
getName():String:获得属性名称。
isAccessible():boolean:判断该属性是否是可以访问的,通常私有和保护的类型都是不可以访问的。
get(Object obj):Object:获得实例obj的属性值,如果该实例的类型中不包含这个属性,那么就会报错。
set(Object obj, Object value):设置该实例的属性值
setAccessible(boolean flag):设置该属性是否可以访问,如果你调用get和set方法,那么有可能会引发访问权限的错误,这个时候你可以调用setAccessible方法使得该属性可以访问。例如下面的代码:
A a = new A();
Field f = A.class.getDeclaredField("a2");
f.setAccessibe(true);
System.out.println(f.get(a));
f.set(a,12);
System.out.println(f.get(a));
如果移出中间的f.setAccessibe(true);那么代码会报错,反之输出0 12。
    对于属性而言,如果该属性的类型是基本类型,那么还可以使用一些便捷的set和get操作,例如getInt,setInt什么的,你可以根据自己的需要调用相应的方法。
 
    对于方法,可以有以下的方法:
getName():String:获得方法的名字。
getReturnType():Class:获得方法的返回值类型。
getParameterTypes():Class[]:获得方法的参数类型。
isAccessible():boolean:判断该方法是否是可以访问的。
setAccessible(boolean flag):设置该方法是否可以访问。
invoke(Object obj, Object... args):Object:调用实例obj的相应方法,其参数由args给定,如果没有参数那么可以什么都不写。
getExceptionTypes():Class[]:获得该方法可能抛出的异常类类型。
这几个方法的含义和用法都和Field的类似,这里不再赘述。

4,创建实例
    利用Class对象可以创建一个类型的实例。如果一个类型拥有无参数的构造函数,那么可以简单地调用Class.newInstance()方法创建一个实例。如果该类型没有无参数的构造函数,或者你希望是用某个有参数的构造函数,那么可以首先使用getConstructors()、 getConstructor(Class[] parameterTypes)和getDeclaredConstructors()、getDeclaredConstructor(Class[] parameterTypes)获得构造函数,这两个方法的返回值都使Constructor类型。特别注意的是,构造函数不能继承,因此你调用 getConstructor也只能返回这个类型中定义的所有公有构造函数。
 
    Constructor的使用方法和Method的类似,它也存在getParameterTypes()方法和getExceptionTypes() 方法,不同的是,它使用newInstance(Object... args)来调用一个构造函数,注意newInstance不需要实例对象,因为这个时候你还没创建出来这个实例呢
分享到:
评论

相关推荐

    Java反射学习.pdf

    Java 反射学习 Java 反射是 Java 程序设计语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说 "自审 ",并能直接操作程序的内部属性。Java 反射的能力在实际应用中非常有价值,例如,使用它能获得 ...

    java反射学习

    在“JAVA反射学习”这个主题中,我们将深入探讨以下几个关键知识点: 1. **什么是反射**:反射是Java提供的一种能力,通过Class对象来获取关于类的所有信息,并能在运行时创建和访问对象,调用方法,甚至修改私有...

    java反射学习资料

    ### Java反射机制详解 在Java领域,反射(Reflection)是一个强大的功能,允许程序在运行时检查和修改其结构和行为。这种能力对于框架设计、动态代理、类库扩展等场景至关重要。下面,我们将深入探讨Java反射的核心...

    Java反射机制的使用和学习方法

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。这一机制对于理解和实现高级框架、动态代理、元数据处理等场景至关重要。以下是对Java反射机制的详细说明:...

    Java反射机制学习(二)

    这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...

    JAVA反射,一定要学的

    这是一个小型的JAVA反射学习教程,权威啊 学习它可以让你更轻松处理复杂问题

    JAVA反射机制的入门代码

    总的来说,"JAVA反射机制的入门代码"是初学者理解Java反射机制的好教材,通过它,你可以学习如何动态地操作Java类,提高代码的灵活性,并掌握处理`properties`文件的基础方法。在深入学习和实践中,你将进一步理解...

    Java反射机制的学习

    Java反射机制是Java编程语言中的一项核心特性,它允许程序在运行时动态地获取类的信息并进行操作。这使得Java能够在编译后仍然能够灵活地处理类和对象,增强了代码的动态性。在Android应用开发中,反射机制尤其重要...

    java面试题--反射机制

    通过本文的学习,我们深入了解了Java反射机制的基本概念、原理以及应用。Java反射机制为Java程序提供了一种强大的动态处理能力,使得Java不仅仅局限于静态类型语言的功能限制。掌握Java反射机制对于开发者来说是非常...

    Java反射经典实例

    Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等信息,即使这些信息在编译时并未明确知晓。...学习和熟练掌握Java反射,能够显著提升编程的灵活性和解决问题的能力。

    java学习笔记(java 反射机制 流 内存管理)

    本笔记主要涵盖了四个核心知识点:Java反射机制、流(I/O流)、内存管理和Java学习的基础。以下是对这些主题的详细阐述: 一、Java反射机制 Java反射机制是Java语言的一个强大特性,允许程序在运行时检查类、接口、...

    Java反射机制学习总结

    Java反射机制是Java编程语言中一个强大的工具,它允许程序在运行时动态地获取类的信息并操作类的对象。反射机制的核心在于java.lang.reflect包中的API,主要包括Class类、Constructor类、Method类和Field类。以下是...

    java反射-英文版反射规范

    ### Java反射机制详解 #### 一、概述 ...通过以上介绍,我们不仅深入了解了Java反射的基本概念和应用场景,还学习了如何利用反射来处理各种类型的数据结构。这对于深入理解和应用Java语言具有重要意义。

    java反射源代码

    对于学习Java反射,阅读和理解相关的源代码是非常有益的。你可以从Java标准库的`java.lang.reflect`包开始,研究Class、Constructor、Method和Field类的实现。通过阅读源码,可以更深入地理解反射的工作原理,提升...

    北大青鸟java反射机制

    在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念:在程序运行时,通过Class对象获取类的信息,包括类名、属性、方法等,并能够动态地创建对象和调用方法。...

    java例子 java反射

    Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是`java.lang.Class`,它代表了类的信息。当我们需要在运行时动态地...

    java注解和反射的个人学习笔记

    java注解和反射的个人学习笔记

    Java反射简单例子

    Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制主要用到了java.lang.Class、java.lang.reflect.Method、java.lang.reflect....

    Java反射学习和反射的应用场景干货都在这里

    Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作,如创建对象、调用方法、访问属性等。在本文中,我们将深入理解Java反射的概念,掌握其核心实现,并探讨它在实际开发中的...

    Java 反射-动态代理

    Java反射和动态代理是Java编程中的重要特性,它们在实现高度灵活...在提供的压缩包文件"JavaReflect"中,可能包含了关于Java反射和动态代理的示例代码和教程,通过学习和实践这些内容,你可以更深入地掌握这两种技术。

Global site tag (gtag.js) - Google Analytics