黑马程序员——Java基础---反射
来源:互联网 发布:2017网络水军招募 编辑:程序博客网 时间:2024/04/29 23:48
-----<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
一.概述及作用
1.概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2.反射的作用
反射的作用总结起来就一个:倒转了目标类和客户类的依赖关系。
以前我们设计程序,客户类要么依赖于目标类,要么依赖于目标类的接口。因为目标类是作为工具提供给客户类使用的,根据java 基本语法规则,要使用某个类,必须知道该类提供的接口。有了反射之后,我们就可以方便是使用反射来实现框架,解除框架对于我们写的类——目标类,的依赖关系。
反射的概念和实现原理
Reflection 是Java被视为动态(或准动态)语言的一个关键性质。反射就是把 JVM 通过符号引用动态解析 java 类的字节码的能力映射成为各种 Java 类的成分类的机制,通过这个机制,java 把 JVM 动态解析符号引用的功能封装为各种 API 类公开给我们使用,这个机制允许我们可以于运行时加载、探知、使用,编译期间完全未知的classes,程序在运行时通过 Reflection APIs 取得任何一个 class 的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields 和 methods 的所有信息,并可于运行时改变该类的对象的 fields 内容或调用该类或者该类对象的 methods。这种动态获取类的信息以及动态调用对象的方法的功能就是Java 语言的反射(Reflection)机制。
Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。 反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使 反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
二.Java类反射中所必须的类:
Java的类反射所需要的类并不多,它们分别是:Class、Field、Constructor、Method、Object.
1).Class类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
2).Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的 理解可以把它看成一个封装反射类的属性的类。
3).Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Co nstructor类则封装了反射类的构造方法。
4).Method类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。 这个类不难理解 ,它是用来封装反射类方法的一个类。
5).Object类:每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
三.举例详解
1.通过一个对象获得完整的包名和类名
<span style="white-space:pre"></span>package Reflect; <span style="white-space:pre"></span>/** <span style="white-space:pre"></span>* 通过一个对象获得完整的包名和类名 <span style="white-space:pre"></span>* */<span style="white-space:pre"></span>class Demo{ <span style="white-space:pre"></span>//other codes...<span style="white-space:pre"></span>} <span style="white-space:pre"></span>class hello{ <span style="white-space:pre"></span>public static void main(String[] args) { Demo demo=new Demo(); System.out.println(demo.getClass().getName()); <span style="white-space:pre"></span>}<span style="white-space:pre"></span>}【运行结果】:Reflect.Demo
2.实例化Class类对象
<span style="white-space:pre"></span>package Reflect;<span style="white-space:pre"></span>class Demo{ <span style="white-space:pre"></span>//other codes...<span style="white-space:pre"></span>} <span style="white-space:pre"></span>class hello{ <span style="white-space:pre"></span> public static void main(String[] args) { Class<?> demo1=null; Class<?> demo2=null; Class<?> demo3=null; try{ //一般尽量采用这种形式 demo1=Class.forName("Reflect.Demo"); }catch(Exception e){ e.printStackTrace(); } demo2=new Demo().getClass(); demo3=Demo.class; System.out.println("类名称 "+demo1.getName()); System.out.println("类名称 "+demo2.getName()); System.out.println("类名称 "+demo3.getName()); <span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>
【运行结果】:
类名称 Reflect.Demo
类名称 Reflect.Demo
类名称 Reflect.Demo
3.通过Class实例化其他类的对象1)通过无参构造实例化对象
package Reflect; class Person{ public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString(){ return "["+this.name+" "+this.age+"]"; } private String name; private int age;} class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Person per=null; try { per=(Person)demo.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } per.setName("Rollen"); per.setAge(20); System.out.println(per); }}
【运行结果】:
[Rollen 20]
2).通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)package Reflect; import java.lang.reflect.Constructor; class Person{ public Person() { } public Person(String name){ this.name=name; } public Person(int age){ this.age=age; } public Person(String name, int age) { this.age=age; this.name=name; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString(){ return "["+this.name+" "+this.age+"]"; } private String name; private int age;} class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Person per1=null; Person per2=null; Person per3=null; Person per4=null; //取得全部的构造函数 Constructor<?> cons[]=demo.getConstructors(); try{ per1=(Person)cons[0].newInstance(); per2=(Person)cons[1].newInstance("Rollen"); per3=(Person)cons[2].newInstance(20); per4=(Person)cons[3].newInstance("Rollen",20); }catch(Exception e){ e.printStackTrace(); } System.out.println(per1); System.out.println(per2); System.out.println(per3); System.out.println(per4); }}【运行结果】:
[null 0]
[Rollen 0]
[null 20]
[Rollen 20]
4.返回一个类实现的接口:
<span style="white-space:pre"></span>package Reflect; <span style="white-space:pre"></span>interface China{ public static final String name="Rollen"; public static int age=20; public void sayChina(); public void sayHello(String name, int age);} <span style="white-space:pre"></span>class Person implements China{ public Person() { } public Person(String sex){ this.sex=sex; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public void sayChina(){ System.out.println("hello ,china"); } @Override public void sayHello(String name, int age){ System.out.println(name+" "+age); } private String sex;} <span style="white-space:pre"></span>class hello{ <span style="white-space:pre"></span>public static void main(String[] args) { <span style="white-space:pre"></span> Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } //保存所有的接口 Class<?> intes[]=demo.getInterfaces(); for (int i = 0; i < intes.length; i++) { System.out.println("实现的接口 "+intes[i].getName()); } }}
【运行结果】:实现的接口 Reflect.China
5.取得其他类中的父类<span style="white-space:pre"></span>import java.lang.reflect.*;<span style="white-space:pre"></span>class hello{ <span style="white-space:pre"></span>public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Constructor<?>cons[]=demo.getConstructors(); for (int i = 0; i < cons.length; i++) { System.out.println("构造方法: "+cons[i]); } }}
【运行结果】:
构造方法: public Reflect.Person()
构造方法: public Reflect.Person(java.lang.String)
6.通过class取得一个类的全部框架<span style="white-space:pre"></span>class hello { <span style="white-space:pre"></span>public static void main(String[] args) { Class<?> demo = null; try { demo = Class.forName("Reflect.Person"); } catch (Exception e) { e.printStackTrace(); } System.out.println("===============本类属性========================"); // 取得本类的全部属性 Field[] field = demo.getDeclaredFields(); for (int i = 0; i < field.length; i++) { // 权限修饰符 int mo = field[i].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = field[i].getType(); System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";"); } System.out.println("===============实现的接口或者父类的属性========================"); // 取得实现的接口或者父类的属性 Field[] filed1 = demo.getFields(); for (int j = 0; j < filed1.length; j++) { // 权限修饰符 int mo = filed1[j].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = filed1[j].getType(); System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";"); } }}
【运行结果】:
===============本类属性========================
private java.lang.String sex;
===============实现的接口或者父类的属性========================
public static final java.lang.String name;
public static final int age;
7.通过反射取得并修改数组的信息
<span style="white-space:pre"></span>import java.lang.reflect.*;<span style="white-space:pre"></span>class hello{ <span style="white-space:pre"></span>public static void main(String[] args) { int[] temp={1,2,3,4,5}; Class<?>demo=temp.getClass().getComponentType(); System.out.println("数组类型: "+demo.getName()); System.out.println("数组长度 "+Array.getLength(temp)); System.out.println("数组的第一个元素: "+Array.get(temp, 0)); Array.set(temp, 0, 100); System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0)); <span style="white-space:pre"></span>}<span style="white-space:pre"></span>}
【运行结果】:
数组类型: int
数组长度 5
数组的第一个元素: 1
修改之后数组第一个元素为: 100
- 黑马程序员——java基础---反射
- 黑马程序员——Java基础---反射
- 黑马程序员——Java基础--- 反射
- 黑马程序员——JAVA基础 反射
- 黑马程序员——Java基础---反射
- 黑马程序员——Java基础---反射
- 黑马程序员——Java基础---反射
- 黑马程序员——Java基础---反射
- 黑马程序员——Java基础---反射
- 黑马程序员——java基础---反射
- 黑马程序员——Java基础---反射
- 黑马程序员——JAVA基础------反射
- 黑马程序员——JAVA基础---反射
- 黑马程序员—JAVA基础—反射
- 黑马程序员——Java基础---反射
- 黑马程序员——Java基础--反射
- 黑马程序员——java基础---反射
- 黑马程序员——Java基础---反射
- APT攻击初步了解
- ubuntu-14.04-desktop-amd64 安装 Bcompare
- HTTP协议的持续连接和非持续连接
- Android应用开发:Fragment与大型数据缓存
- HDU2203 亲和串【KMP】
- 黑马程序员——Java基础---反射
- Android APK的签名与重新签名
- C/C++宏的使用总结
- HDU-1059 Dividing(DP)
- 给10^7个数据量的磁盘文件排序
- div+css之清除浮动
- 给出一个数和一个有序数组,找出该数组中之和等于该数的两个数
- 菜单点击 显示和隐藏
- 使用jdbc连接mysql数据库