您的位置:首页 > 职场人生

黑马程序员——Java基础---反射

2015-04-26 09:26 155 查看
-----<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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: