透彻分析反射的基础_Class类
Class类:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class
如何得到各个类的字节码,即Class类?
1、类名.class //直接使用类.class获得
2、对象.getClass()//通过对象调用其getClass方法
3、Class.forName(“java.util.Date”) //使用类加载器加载
Java原始基本类型:boolean, byte, char, short, int, long, float,double 和关键词 void同样都有Class类,通过.class可获得他们的类字节码
理解反射的概念
反射就是吧Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就想七成是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。
构造方法的反射应用
Constructor 类,各种类的构造方法的反射类。
Constructor 反射类对象的获得:
例:Constructor constructor=String.class.getConstructor(StringBuffer.class);
构造方法可以用于构造实例对象
String str=(String)constructor.newInstance(new StringBuffer("abc"));
Class本身也还有newInstance方法,可以直接调用,例如
String obj=(String)String.class.newInstance();
//类似于调用无参的构造方法。
成员变量的反射
Field 类,类中成员变量的反射类。
Field 对象的反射获得:
class Person
{
public String personname;
protected String personcity;
private String personadd;
public int personage;
public Person(String personname, String personcity, String personadd)
{
this.personname = personname;
this.personcity = personcity;
this.personadd = personadd;
this.personage=0;
}
}
......
//一下为Field反射类的应用部分
......
Person person=new Person("myname","mycity","myaddress");
Field fieldname=person.getClass.getField("personname");//基本方式获得public成员变量
Field fieldcity=person.getClass.getDeclaredField("personcity");//获得声明的成员变量
Field fieldadd=person.getClass.getDeclaredField("personadd");//获得声明的成员变量
//Field[] fields=person.getClass.getDeclaredFields();//获得声明的所有成员变量数组
System.out.println("personname:" + fieldname.get(person));//打印成员变量的值
System.out.println("personcity:" + fieldcity.get(person));//protect修饰变量可直接读取
personadd.setAccessible(true);//设置成员变量可访问,包括private成员变量(暴力反射)
System.out.println("personcity:" + fieldadd.get(person));//private成员必须设置访问权限setAccessible(true)后才可以访问
成员变量的修饰符public、protect、private对反射类有不同的权限要求,注意红色字体部分。
成员变量反射的综合案例
循环访问类示例对象的成员变量,并修改其变量值:
public class Java_Test //声明运行主体类
{
public Java_Test()
{
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws Exception
{
System.out.println("-------------------------------");
Person person=new Person("myname","mycity","myaddress");
System.out.println(person.toString()); //打印原始对象成员变量的值
System.out.println("-------------------------------");
chageFields(person); //调用方法访问并修改类成员变量的值
System.out.println(person.toString()); //打印修改后的成员变量值
System.out.println("-------------------------------");
}
public static void chageFields(Object obj) throws IllegalAccessException
{
String str;
Field[] fields=obj.getClass().getDeclaredFields(); //获得成员变量反射类对象数组
for(Field field:fields) //循环访问数组成员
{
field.setAccessible(true); //设置成员变量可访问(暴力反射)
if(field.getType()==String.class)
{
str=(String)field.get(obj); //读取成员变量的值
str=str.replace('_',' '); //修改
field.set(obj,str); //重新设置成员变量的值
}
}
}
}
class Person //声明要操作的类
{
public String personname;
protected String personcity;
private String personadd;
public int personage;
public Person(String personname, String personcity, String personadd)
{
this.personname = personname;
this.personcity = personcity;
this.personadd = personadd;
this.personage=0;
}
@Override //覆盖toString方法,显示成员变量的值
public String toString()
{
return "personname:" + personname +"\npersoncity:"+personcity + "\npersonadd:" + personadd;
}
}
成员方法的反射
Method 类,类中各个成员方法的反射类
成员方法的反射应用方法:先得到类字节码的方法,然后再指定在哪个对象上调用方法,最后进行调用。
例如:利用反射调用String类的charAt方法
String str=new String("abc")
Method methodCharAt=String.class.getMethod("charAt",int.class);
//注意参数类型及意义:类字节码class.getMethod(“方法名”,方法参数类型.class)
System.out.println(methodCharAt.invoke(str,1)); //方法对象.invoke(原对象,参数对象数组)
输出结果同直接调用对象方法,即:str.charAt(1)
*注意* 静态方法的反射调用可以写成:方法对象method.invoke(null,参数对象数组)
无参静态方法反射调用要写成:方法对象method.invoke(null,null)
JDK1.4版本注意参数类型构成:methodCharAt.invoke(str,new Object[]{1})
对接收数组参数的成员方法进行反射
示例:调用其他类的main方法 public static void main(String[] args)
String mainClassName=new String("MainClassName");
Method mainMethod=Class.forName(mainClassName).getMethod("main", String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"Ling","Dong","Cao"}});
mainMethod.invoke(null, (Object)new String[]{"Ling","Dong","Cao"});
为兼容JDK1.4,invoke会将数组参数拆分为单个的元素来作为参数列表。在以上示例中如果直接使用数组作为参数,则会出现main方法参数个数错误:
//错误的写法:mainMethod.invoke(null,new String[]{"Ling","Dong","Cao"});
数组与Object的关系及其反射类型
1、具有相同维数和元素类型的数组属于统一个类型,即具有相同的Class实例对象
2、代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
3、基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用,非基本类型的一维数组既可以当做Object类型使用,又可以当做Object[]类型使用。
示例:
int[] num1=new int[3];
int[] num2=new int[4];
int[][] num12=new int[3][4];
String[] str=new String[3];
下面说明各个对象的反射类的关系
num1.getClass()==num1.getClass()
num1.getClass()!=num12.getClass()
num1.getClass()!=str.getClass()
数组与Object的关系:
num1.getClass().getSuperClass().getName()==str.getClass().getSuperClass().getName()=="java.lang.Object"
Object objint1=num1;
Object objint12=num12;
Object objstr=str;
//Object[] objint=num1; //错误的写法,int基本类型不是Object
Object[] objint12=num12; //正确写法,因其成员为int[],为Object。
Object[] obj_str=str; //正确,因为String实例即为Object对象类型
Array.asList()方法处理int[]和String[]的差异。
int[] num=new int[]{1,2,3};
String[] str=new String[]{"aaa","bbb","ccc"};
System.out.println(Arrays.asList(num1)); //打印输出类似“[[I@c17164]”的字符
System.out.println(Arrays.asList(str)); //打印类似“[aaa, bbb, ccc]”的字符
数组的反射应用
打印传入对象,如果为单一对象,直接打印,如果为数组,则逐一打印数组元素(对数组对象的判断应用)
public void printObject(Object obj)
{
Class cla=obj.getClass();
if(cla.isArray())
{
int len=Array.getLength(obj);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(obj,i));
}
}
else
{
System.out.println(obj);
}
}
分享到:
相关推荐
2. **序列化与反序列化**:通过反射可以将对象的状态转换为XML或JSON格式,然后在需要时恢复。 3. **动态代码生成**:反射可以用于创建和编译动态方法,实现运行时代码生成。 4. **日志记录和调试**:获取类和方法的...
#### 二、反射基本概念 反射可以让我们在运行时获取.NET类型的所有信息,包括类、结构体、委托、接口和枚举等。通过反射,我们可以获取这些类型成员的详细信息,比如方法、属性、事件以及构造函数等,并且可以进一步...
光的反射原理是光学中一项基础而重要的概念,它的研究涉及物理学、工程学以及建筑学等多个学科领域。光的反射不仅能够帮助我们解释和理解自然界中的诸多现象,还为光学仪器的设计、建筑照明的创新以及艺术创作中的...
反射的概念源于1982年Smith的提出,它指的是程序可以自我检测和修改其状态或行为的能力。在计算机科学领域,反射意味着应用能够自我描述和自我控制,通过某种机制获取自身行为的描述并进行监测,甚至根据这些信息...
反射的常见应用场景包括:动态加载类、调用私有方法、遍历类的结构、序列化和反序列化等。Java.lang.Class类是反射的核心,通过对象的Class对象,我们可以获取到类的各种信息,如构造器、方法和字段。java.lang....
1. **反射的基本概念** - 类加载:Java程序运行时,JVM会将.class文件加载到内存中,形成Class对象。 - 获取Class对象:通过Class.forName()、对象.getClass()或类名.class三种方式获取。 - 对象实例化:通过...
结构反射侧重于元类与类之间的关系,计算反射则关注于计算层面上的应用领域相关目标计算和系统自身的反射计算。在编程语言中,反射通常指的是程序在执行过程中对表示程序状态数据的操纵能力,具体体现在内省和调解两...
框架技术在当前的软件开发中占据着举足轻重的地位,其灵活性和可扩展性很大程度上得益于反射技术的应用。 当框架无法预知所有类及其行为时,它们通常依赖于外部配置文件来定义这些类和方法。反射技术使得程序能够在...
综合上述分析,MATLAB在光学界面发生反射现象的分析与应用中扮演了重要的角色,它不仅帮助学生和研究者深入理解光学理论,还推动了光学教学和研究方法的发展。随着计算技术的进步,MATLAB在光学乃至更多领域的应用...
反射是C#的一个重要概念,如何使用很重要,有必要抽时间好好学习一下!
本文通过对反射率与能带关系的深入分析,展示了一系列经典小案例,旨在让读者对这两个在物理学和材料科学领域中至关重要的概念有一个清晰和全面的认识,并理解它们在现代科技发展中的重要应用。
#### 一、Java反射机制的基本概念 反射(Reflection)是指程序在运行时能够访问、检测和修改它自身的能力。这种能力使得程序能够动态地获取自身的结构信息并操作自身的结构,从而达到灵活编程的目的。在计算机科学...
反射的概念: 反射是.NET框架提供的一种能力,它允许代码在运行时分析自身,获取类型信息,创建和操作类型实例。通过反射,开发者可以访问类、接口、方法、属性等元数据,甚至可以在不知道它们具体类型的情况下调用...
《C++反射的应用与实践.pdf》文档详细介绍了C++中的反射概念、应用场景、现状、以及如何在项目中应用反射技术。 首先,反射是指程序对自身程序结构的认知能力。具体而言,这包括使用数据结构描述数据类型及其成员,...
9. 反射在生活中的应用:训练动物表演、人类的学习行为、恐惧反射的形成和消退等都涉及到反射的概念。 综上所述,本训练主要涵盖了生物学中关于反射的基本概念、分类、形成机制以及在高等动物中的重要性。通过这些...
内容概要:本文详细介绍了Java泛型与反射两个重要特性的基础理论与应用技巧。首先阐述了Java泛型的基础概念及优势——确保类型安全的同时提高代码复用性,并通过一系列具体的代码案例演示如何定义并利用泛型类、泛型...
可能是针对太阳能反射跟踪系统的全面介绍,涵盖了从基本概念到具体实施的所有关键点。 标签“行业分类-设备装置-反射式太阳能”进一步细化了讨论的焦点,强调了这是一个与反射式太阳能技术和相关设备有关的专题,...
这篇压缩包文件提供了关于C#反射的实践示例,通过四个主要的子文件:`DataTableAOP`、`Model`、`ReflectionTest`和`ObjectLoader`来深入理解这一概念。 1. **反射的基本原理**: 反射的核心是`System.Reflection`...
反射实例,如标题所示,旨在帮助我们深入理解这一关键概念,并应用它来实现自动升级和插件技术。让我们详细探讨一下这些知识点。 首先,我们要理解什么是反射。在.NET中,反射提供了一种在运行时获取类型信息并使用...
电磁波透射系数和反射系数是电磁波理论中的两个重要概念,它们描述了电磁波在介质界面上的行为。在本节中,我们将详细介绍电磁波透射系数和反射系数的定义、计算公式、物理意义,以及其在实际应用中的重要性。 一、...