`
Strive_sprint
  • 浏览: 22496 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

初识java反射机制

 
阅读更多

 

什么是java反射机制

      对于一个类,可以知道类中的所有属性和方法,对于一个对象,可以调用他的属性和方法,这种动态获取信息和动态调用对象的方法就叫做反射机制。其实说白了就是通过java代码获取装载到方法区的类信息一种手段。

 

java反射机制有什么用

      反射允许程序在运行时通过reflection的API取得任何一个已知名称的class内部信息,也可以称为java类的自审。

 

java反射机制的基础

      1.Class类

         当一个.class文件被装载到JVM后,JVM就会自动产生一个Class对象,通过这个Class对象,我们就能获得加载到JVM中这个Class对象方法,属性等信息。

      2.java.lang.reflect包

         在这个包中有很多的接口和类,正是因为有这个类库的支撑,正是因为有反射的API,我们才能得到JVM中类的信息。

 

下面是一些API的介绍:

      得到所要操作的Class对象(这个查下Class的API中有很多的方法),如:

Class c = Class.forName("reflection.Demo");

       是不是似曾相识,不错,在JDBC中得到驱动的时候用过。不过这里可能会抛出ClassNotFoundException异常。

 

      1.得到类中的构造方法

         getConstructor(Class<?>...parameterTypes);

         getDeclaredConstructor(Class<?>...parameterTypes);

         getConstructors();

         getDeclaredContructors();

         在这么多的方法中,其中带有Declared的表示获取所有申明的构造方法,不管是"public","protected",默认的还是"private",而不带Declared的表示获取的是申明为"public"的内容。不带参数的表示获取所有能获取的构造方法,而带参数的表示构造方法的参数类型。如:

Person类:

public class Person {
	public String name;
	protected int age;
	String sex;
	private boolean isStudent = true;
	private Person(String name){
		this.name = name;
	}
	Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	protected Person(String name,int age,String sex){
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	public Person(String name,int age,String sex,boolean isStudent){
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.isStudent = isStudent;
	}
}

 测试类:

public class Test2 {
	public static void main(String [] args) throws Exception{
		Class<?> c = Class.forName("reflection.Person");
		Constructor<?> []con1 = c.getConstructors();
		Constructor<?> []con2 = c.getDeclaredConstructors();
		Constructor<?> con3 = c.getDeclaredConstructor(String.class,int.class);
		for(int i = 0;i<con1.length;i++){
			System.out.println(con1[i].toString());
		}
	        System.out.println("=============================");
		for(int i = 0;i<con2.length;i++){
			System.out.println(con2[i].toString());
		}
	        System.out.println("=============================");
		System.out.println(con3);
		Person per = (Person) con3.newInstance("张三",20);//用得到的构造函数创建对象
	}
}

       结果为:

public reflection.Person(java.lang.String,int,java.lang.String,boolean)
=============================
public reflection.Person(java.lang.String,int,java.lang.String,boolean)
protected reflection.Person(java.lang.String,int,java.lang.String)
reflection.Person(java.lang.String,int)
private reflection.Person(java.lang.String)
=============================
reflection.Person(java.lang.String,int)

 

      2.得到类中的属性

         getField(String name);

         getDeclaredField(String name);

         getFields();

         getDeclaredFields();

         和构造方法差不多的,参数指的是属性的名字,如修改Person类中的私有isStudent属性:

public class Test2 {
	public static void main(String [] args) throws Exception{
		Class<?> c = Class.forName("reflection.Person");
		Person per = (Person) c.newInstance();
		Field field = c.getDeclaredField("isStudent");
		field.setAccessible(true);
		field.setBoolean(per, false);
	}
}

      在这里会报异常:

Exception in thread "main" java.lang.InstantiationException : reflection.Person
      查API发现,当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化,就会抛出该异常。这是因为newInstance()只能调用无参构造方法,当我们在Person类中加个无参构造方法后,就不会报这个异常了。我们都知道当我们重载了构造方法后,无参构造方法不写的话就没有了。

      这里有个方法,field.setAccessible(true),如果没这句,就会报下列异常,不允许改变private属性:

Exception in thread "main" java.lang.IllegalAccessException : Class reflection.Test2 can not access a member of class reflection.Person with modifiers "private"

      要改变类中的属性,只要调用field.setXXX(Object,Object)方法,如果是该布尔属性就是setBoolean,第一个参数是要改变属性的对象,第二个是要改变成的值。如果是静态属性,第一个参数就是null。

 

      3.得到类中的方法

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

         getDeclaredMethod(String name,Class<?>...parameterTypes);

         getMethods();

         getDeclaredMethods();

         和前面介绍的差不多,这里介绍一下参数,第一个String name表示的是方法名,第二个是参数类型:

Person类:

public class Person {
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void print(){
		System.out.println("测试一下");
	}
}

 测试类:

public class Test3 {
	public static void main(String [] args) throws Exception{
		Class<?> c = Class.forName("reflection.Person");
		Person per = (Person) c.newInstance();
		Method m1 = c.getMethod("print");
		Method m2 = c.getMethod("setName", String.class);
		Method m3 = c.getMethod("getName");
		m1.invoke(per);
		m2.invoke(per, "张三");
		String name = (String) m3.invoke(per);
		System.out.println(name);
	}
}

       结果:

测试一下
张三
      通过调用getMethod()方法得到Method对象,然后调用invoke()方法,invoke()方法中,第一个参数代表的是哪个对象调用了类Person中的方法,第二个就是传的参数。

 

      有了反射,一个类中的私有属性和方法也可以被我们调用。

 

      这里只是简单的介绍了一下反射最基本的应用,其性能,安全性和AOP代理后面再做分析。

分享到:
评论

相关推荐

    初识Java_课后补充作业

    11. **反射**:通过反射机制,可以在运行时动态地获取类的信息并调用类的方法。 12. **泛型**:理解泛型的作用,如何在类、接口、方法中使用泛型,以及通配符的概念。 13. **注解**:注解在代码中提供了元数据,...

    1.初识Java.zip

    【初识Java】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(后被Oracle公司收购)于1995年发布。它的设计目标是具备“简单性、面向对象、健壮性、安全性、可移植性、高效性、多线程和动态性”等...

    Java反射总结:入门进阶到使用

    Java反射是Java编程语言的一...综上所述,Java反射机制提供了强大的动态操作能力,但同时也带来了性能损耗和安全风险,因此在使用时需要权衡利弊。在理解反射机制的基础上,我们可以编写更加灵活和适应性强的Java程序。

    java基础的文档

    本文档“初识Java_第18页_下载资料.pdf”可能涵盖了以上部分或全部内容,帮助初学者建立起对Java语言的基础认识,进一步深入学习Java的高级特性,如异常处理、多线程、网络编程、反射机制、注解、模块化系统等。...

    Java技术文档

    7. **反射机制**:反射是Java的动态特性,允许在运行时检查类、接口、字段和方法的信息,甚至可以动态调用方法。文档会解释如何使用Class类和反射API。 8. **泛型**:泛型引入了类型安全,使得容器可以存储特定类型...

    Beginning_Java_Se_6__Platform_From_Novice_to_Professional.rar

    最后,书中还将涉及Java的反射机制和动态代理,这些高级特性允许在运行时检查和修改类的行为,对于框架开发和元编程尤其有用。 总而言之,《初识Java SE 6平台:从新手到专业》是一本全面且深入的教程,它将引领...

    beginning java

    《初识Java:JDK1.5入门精典》是一本专为新手设计的Java编程教程,基于Java Development Kit(JDK)1.5版本。这本书深入浅出地介绍了Java编程语言的基础概念和核心特性,旨在帮助读者快速掌握Java编程技能。 首先,...

    实用Java自学课件

    通过这些详细讲解和实例分析,"实用Java自学课件"将帮助你逐步提升Java编程技能,从初识Java到能够独立进行项目开发,踏上Java编程的殿堂之旅。无论你是零基础的新手,还是希望深化理解的开发者,这个课件都将是你...

    清华大学java课件

    9. **反射与注解**:反射机制允许在运行时动态访问类的信息,注解则提供了一种元数据的方式,这两者在Java开发中都有重要的应用。 10. **Java高级特性**:这部分可能包括泛型、枚举、匿名内部类、Lambda表达式等,...

    《Java语言程序设计》源代码

    5. **chapter2**:初识Java,可能包含基本语法,如变量声明、数据类型、运算符、流程控制(if、for、while)等,以及简单的函数和方法。 6. **chapter36**:可能涉及的是输入/输出流的更深入话题,如对象序列化或...

    java21-25

    每节课之间的内容可能相互关联,构建起一个完整的知识体系,帮助学习者从初识Java到能够独立开发应用程序。总的来说,"java21-25"是一套系统化的Java学习资源,适合初学者和有一定基础的开发者进行自我提升。

    java核心技术I-II

    3. ** HelloWorld程序**:初识Java,编写第一个"Hello, World!"程序,理解编译和运行过程。 4. **基本语法**:包括数据类型(整型、浮点型、字符型、布尔型)、变量、常量、运算符的使用。 5. **流程控制**:条件...

    Beginning_Java_Objects

    《初识Java对象》这本书是Jacquie Barker的著作,主要关注Java编程中的面向对象概念与实践。本书的第二版旨在帮助读者从基础概念到实际编码,全面理解Java中的对象和面向对象编程。 面向对象编程(Object-Oriented ...

    初识JVM – JVM概念.pdf

    ### 初识JVM – JVM概念 #### 一、JVM简介 JVM,即Java Virtual Machine(Java虚拟机),是一种能够执行特定机器指令的虚拟机。它通过软件模拟了一个完整的计算机系统,允许Java程序在任何支持JVM的平台上运行而...

    java 习题与解答

    1. **初识JAVA**: - ** HelloWorld 示例**:学习Java的第一步通常是编写"Hello, World!"程序,了解基本语法和编译运行流程。 - **JDK和JRE**:理解Java Development Kit (JDK)和Java Runtime Environment (JRE)的...

    Java就业培训教程

    "程序,初识Java的基本语法结构。 3. **数据类型**:包括基本数据类型(如整型、浮点型、字符型和布尔型)和引用数据类型(如类、接口和数组)。 4. **变量与常量**:理解变量的声明、初始化和作用域,以及常量的...

    Java_Study:Java学习

    1. **Java基础**: 从初识Java开始,了解它的历史背景、特点以及应用领域。学习基础语法,包括变量、数据类型、运算符、控制结构(if、for、while)、方法和类的定义。此外,还需掌握对象和类的概念,理解封装、继承...

    JavaSE面试题及其参考答案.doc

    6. **反射机制**:动态加载类,获取类信息,调用方法,创建对象。 以上只是JavaSE面试中的部分核心知识点,实际面试中还会涉及更深入的设计模式、网络编程、数据库连接等内容。全面理解和掌握这些知识对于成为一名...

    Java技能学习路线图及重要知识点总结.docx

    - **反射**: 学习Java反射机制及其在程序设计中的应用。 #### 二、JavaEE企业开发(就业知识点) ##### 第1章 HTML - **HTML概述**: 了解HTML的基本结构和语法规则。 - **常见标签**: 学习常用的HTML标签及其用途...

Global site tag (gtag.js) - Google Analytics