手记

Thinking in java基础之反射

Thinking in java基础之反射

java反射的类位于java.lang.reflect包

事先声明:《Thinking in java》第四版中并无此章节,以这个名字开头,实际上是为了和前面的系列同步,也是自我知识体系中重要的一部分。因此有必要说一说。
先贴张图片(反射的一些方法总结)

  1. 反射的理解
    先来说说什么叫做动态语言?程序运行中,允许改变程序结构或者变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,java不是动态语言。但是呢,java给我们提供的反射机制,又有一部分反射的实质。我们可以在程序运行过程中,查看类的信息,调用类的方法等。这也是弥补她的不足。
    另外,有很多流行的框架中也是使用到了反射的原理,例如Struts2,Spring等。作为一个学习者,虽然我们现在不可能开发框架,但是学一下反射,也可以让我们更好的理解一些框架的原理。(也许以后我们就开发框架了呢,想想都是多么开心的事)。就像我之前写的关于JVM的文章,我们不是JVM的设计者,但我们仍要了解一下,毕竟我们的程序运行在他上面啊。扯远了。下面就进入主题。
  2. Class类(类的类型java.lang.Class)

    Class和Object两个类,是参考了【鸡和蛋】的原理设计的吧。

所有的类都最终继承自Object类,Class是类,那么Class也继承自Object类。Object类中有getClass();方法,返回Class实例。所以说,所有的类都有类类型并且都可以通过getClass();得到。

  1. 类信息 (类型 包名,类名,继承的父类,实现的接口,函数信息,成员信息等)
    三种方法获取类类型:对象.getClass(); Class.forName(); 类.class
    其中使用最多的是【 Class.forName();】
    类名,包名

getName() ;

以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。

getPackage() ;

获取此类的包

继承,实现

getSuperclass() ;

返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。

getInterfaces() ;

确定此对象所表示的类或接口实现的接口。

修饰符,属性,方法,参数,返回值

getModifiers() ;

返回此类或接口以整数编码的 Java 语言修饰符。

要进行访问的类

class use {
    private Integer id;
    private String name;
    public String test;
    private use(Integer id,String name){
        this.id=id;
    }
    private use(){
    }
    public use(Integer id){
        this.id=id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    private void doSomething() {
        System.out.println("===private Method======");
    }
}

测试类

public static void main(String[] args) throws NoSuchMethodException, SecurityException {
    Class clazz=use.class;
    System.out.println("=====getConstructors()==============");
    for (int i = 0; i < clazz.getConstructors().length; i++) {
        System.out.println(clazz.getConstructors()[i]);
    }
    System.out.println("=====getDeclaredConstructors()==============");
    for (int i = 0; i < clazz.getDeclaredConstructors().length; i++) {
        System.out.println(clazz.getDeclaredConstructors()[i]);
    }
    System.out.println("=====getFields()==============");
    for (int i = 0; i < clazz.getFields().length; i++) {
        System.out.println(clazz.getFields()[i]);
    }
    System.out.println("=====getDeclaredFields()==============");
    for (int i = 0; i < clazz.getDeclaredFields().length; i++) {
        System.out.println(clazz.getDeclaredFields()[i]);
    }
    System.out.println("=====getMethods()==============");
    for (int i = 0; i < clazz.getMethods().length; i++) {
        System.out.println(clazz.getMethods()[i]);
    }

    System.out.println("=====getDeclaredMethods()==============");
    for (int i = 0; i < clazz.getDeclaredMethods().length; i++) {
        System.out.println(clazz.getDeclaredMethods()[i]);
    }
    }

测试结果

=====getConstructors()==============
public Reflect.use(java.lang.Integer)
=====getDeclaredConstructors()==============
public Reflect.use(java.lang.Integer)
private Reflect.use()
private Reflect.use(java.lang.Integer,java.lang.String)
=====getFields()==============
public java.lang.String Reflect.use.test
=====getDeclaredFields()==============
private java.lang.Integer Reflect.use.id
private java.lang.String Reflect.use.name
public java.lang.String Reflect.use.test
=====getMethods()==============
public java.lang.String Reflect.use.getName()
public java.lang.Integer Reflect.use.getId()
public void Reflect.use.setName(java.lang.String)
public void Reflect.use.setId(java.lang.Integer)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
=====getDeclaredMethods()==============
public java.lang.String Reflect.use.getName()
public java.lang.Integer Reflect.use.getId()
public void Reflect.use.setName(java.lang.String)
public void Reflect.use.setId(java.lang.Integer)
private void Reflect.use.doSomething()

4 Constructor(构造方法) Field(属性) Method(方法)
以上三者的相同之处:带有Declared的方法可以访问所有类的对应信息,没有带Declared的方法只能访问public修饰的信息
5 Annotation(注解,1.5的新特性)
类,属性,方法都有可能被注解修饰,因此,三个(Class,Field,Method)类都有包含获取注解信息的方法。

getAnnotations();

返回此元素上存在的所有注释。

getAnnotation(Class<A> annotationClass);

如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

getDeclaredAnnotations() ;

返回直接存在于此元素上的所有注释。
6 使用类类型实例化对象
newInstance();方法

Class clazz=use.class;
clazz.newInstance();

7 ClassLoader类加载器信息

getClassLoader() ;返回该类的类加载器。

类加载器的信息,请参考深入理解JVM之类加载
8.欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
9.参考文献
反射详解 反射是否真的会让你的程序性能降低?
一个例子让你了解Java反射机制 中文JavaAPI文档列表

8人推荐
随时随地看视频
慕课网APP