`

Java反射初探

阅读更多
    目前非常多的开源框架的工作核心和底层实现原理都是基于反射来工作的。我这边也是闲来无事,公司那边等着走流程签合同,就自己看着JDK的API文档,并结合以前用过的一点知识,做了下反射的简单事例。
    首先反射的具体功能是发现类的方法、属性、构造器(包含私有属性、方法和构造器)。网上众多的所谓动态代理的实现大多也是通过反射来实现的。
    涉及Java包主要为java.lang.Class,java.lang.reflect,我的JDK版本是1.6的。
    由于时间有限,我这次也是浅尝,下次在进一步研究和更新。

    这里只有两个类:为了好看,我将测试方法和发现的机制放到了同一个类(ReflectDemo )中如下:
package com.xiaoyun.reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
* 反射机制学习
*
* @author XiaoYun 2013-07-10
*/
public class ReflectDemo {
public static void main(String[] args) throws Exception {
Person person = new Person(1,1,1.0,"中国人", false);
reflect(person);
}

/**
* 反射功能
* 用于发现 obj的类型
* obj的方法
* obj的属性
* obj的构造器
* @param obj 用户被发现的对象
*/
public static void reflect(Object obj) {
Class cls = obj.getClass();

//发现该类的类型
String clsName = cls.getSimpleName();
System.out.println("类名:" + clsName);
//发现该类的属性
//返回该对象所表示的类或接口中声明的所有字段
Field[] allFields = cls.getDeclaredFields();
//返回该对象表示的类或接口中声明的公共字段
//Field[] unPrivateFields = cls.getFields();
StringBuilder fields = new StringBuilder(150);
fields.append("声明的属性:");
//组装打印到控制台的字段
for (Field field : allFields) {
Annotation[] annotations = field.getAnnotations();
fields.append(field.getName()).append(",").append(field.getType().getName()).append(",").
append(annotations.length).append("\n");
}
System.out.println(fields.toString());
//发现该类的方法(包含私有方法)
Method[] methods = cls.getDeclaredMethods();
//组装打印到控制台的方法描述
StringBuilder methodsStr = new StringBuilder(100);
methodsStr.append("方法的声明:");
for (Method method : methods) {
methodsStr.append(method.getName()).append(",");
//形参类型
Class[] clazz = method.getParameterTypes();
for (Class c : clazz) {
System.out.println(c.getSimpleName());
}
}
methodsStr.deleteCharAt(methodsStr.lastIndexOf(","));
System.out.println(methodsStr.toString());
//发现该类的构造器
//返回该对象表示的类的所有公共的构造方法
Constructor[] unPrivateConstructors = cls.getConstructors();
//发现该对象表示的类所声明的所有的构造方法
Constructor[] allConstructors = cls.getDeclaredConstructors();
//组装打印到控制台的构造器描述
StringBuilder constructors = new StringBuilder(150);
constructors.append("构造器:");
for (Constructor constructor : allConstructors) {
constructors.append(constructor.getName()).append(",");
Class[] types = constructor.getParameterTypes();
for (Class class1 : types) {
constructors.append(class1.getName()).append("\n");
}
}
constructors.deleteCharAt(constructors.lastIndexOf(","));
System.out.println(constructors.toString());
}
}
测试你也可以使用Class.forName("java.lang.String")等来获取对象的方法和属性,我这里是使用的自己又创建了一个Pojo类(Person):
package com.xiaoyun.reflect;


/**
* 人实体类
*
* @author XiaoYun 2013-07-10
*/
public class Person {

private static Person instance = new Person();

/** 年龄 */
private Integer age;
/**  身高*/
private Integer height;
/** 体重 */
private double weight;
/** 描述 */
private String desc;
/** 婚否 */
private boolean isMarry;

private Person() {
}

public Person(int age, int height, double weight, String desc,
boolean isMarry) {
super();
this.age = age;
this.height = height;
this.weight = weight;
this.desc = desc;
this.isMarry = isMarry;
}

public static Person getInstance() {
return instance;
}
        
         //说明,这里是为了测试反射机制能发现私有方法而对get方法做的修改
private Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public Integer getHeight() {
return height;
}

         //说明,这里是为了测试反射机制能发现私有方法而对get方法做的修改
private void setHeight(Integer height) {
this.height = height;
}

public double getWeight() {
return weight;
}

public void setWeight(double weight) {
this.weight = weight;
}

public String getDesc() {
return desc;
}

public void setDesc(String desc) {
this.desc = desc;
}

public boolean isMarry() {
return isMarry;
}

public void setMarry(boolean isMarry) {
this.isMarry = isMarry;
}
}

代码在我的电脑上运行过,完全正常,代码可以直接粘贴,只不过打印出来的属性的类别,Integer打印出来的是int,boolean是boolean,String是java.lang.String,是正常的,我认为可能是JDK编译的时候还是把Integer类型当做简单类型来编译的,所以打印出来的没有在lang包中。

你也可以在获取该实例的属性、方法后,调用该方法。

关于动态代理的具体实现,下次在发布。这次的重点是掌握反射机制的原理。即java.lang.Class包和java.lang.reflect.Field,java.lang.reflect.Method,java.lang.reflect.Construct的使用。
下次将对JDK或CGLIB对动态代理的实现原理做演示和讲解。

初次发布自己写的东西,不合适和不完整的地方欢迎各位同行和前辈们批评指正。谢谢
下次
分享到:
评论

相关推荐

    Java高级编程课程思政案例教学初探.zip

    Java高级编程课程思政案例教学初探,是一个深入探讨如何将思想政治教育融入到Java高级编程教学中的主题。在当前的教育环境中,强调立德树人,将思政元素与专业课程相结合,旨在培养具备良好品德和社会责任感的IT人才...

    C# 通过反射初探ORM框架的实现原理(详解)

    C# 通过反射初探ORM框架的实现原理 在本文中,我们将探讨C# 通过反射初探ORM框架的实现原理。ORM框架是Object-Relational Mapping的缩写,主要用来实现对象和关系数据库之间的映射。在Java中,我们经常使用Mybatis...

    Java-program-design-.rar_Java 8

    压缩包可能还涵盖了异常处理、类和对象、继承、接口、抽象类、访问修饰符、封装、构造器、集合框架(List、Set、Map)、IO流、反射、枚举、泛型等Java 8的关键特性。 每个章节都会通过实例和练习帮助学习者巩固所...

    first:2015 年 IT 学校练习

    【标题】2015年IT学校练习:Java编程初探 在2015年的IT教育领域,Java编程语言以其强大的跨平台能力和丰富的库支持,成为许多学习者入门编程的首选。本练习旨在帮助学生熟悉Java语言的基础概念,掌握编程的基本技能...

    Ioc注入讲解

    这通常是通过Java的反射机制来实现的。反射提供了在运行时动态访问和操作类的能力,主要包括以下几个方面: - **Class对象**:可以通过类名或者实例来获取一个类的Class对象,进而访问该类的所有信息。 - **...

    monte-carlo-raytracer

    《基于Java的Monte Carlo光线追踪器初探》 光线追踪是一种高级的计算机图形学技术,用于模拟光在三维空间中的传播,以生成逼真的图像。Monte Carlo光线追踪是光线追踪的一种方法,它利用随机采样技术来解决复杂的...

    DLP_Repository:DLP(编程语言设计)实践的存储库

    DLP_Repository是一个专注于编程语言设计实践的存储库,主要以Java编程语言为载体进行讨论和实现。...无论是对Java编程语言的深度挖掘,还是对编程语言设计的初探,DLP_Repository都是一个宝贵的资源。

    qt学习之路.pdf

    在Java中,GUI是其标准库的一部分,而对于C++来说,GUI编程并非标准内容。因此,对于C++开发者来说,需要依赖第三方库来完成GUI的开发。本书推荐的Qt框架,是C++开发者广泛使用的一个跨平台GUI开发库。 2. Hello, ...

Global site tag (gtag.js) - Google Analytics