美文网首页
java反射初探

java反射初探

作者: 哦丶那么棒 | 来源:发表于2017-04-20 17:03 被阅读20次

反射(Reflection)?

它是java语言特有的,其他语言并无此特性,其能力是在程序运行期间中,检查,操作,程序的内部属性。

Class对象?

它是jvm生成用来保存对应类的信息的,当我们定义好一个类文件并编译成.class字节码后,编译器同时为我们创建了一个Class对象并将它保存.class文件中。所以说只要拿到class对象即可操作对应类了。

注解?

是java语言5.0版本加入的特殊语法元数组,java语言中的类,方法,变量,参数,包都可以被标注。

1.代码的注解

@Override - 检查该方法是否是重载方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。

2.作用在其他注解上的注解()

@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
@Documented - 标记这些注解是否包含在用户文档中。
@Target - 标记这个注解应该是哪种 Java 成员。
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

3.从 Java 7 开始,额外添加了 3 个注解:

@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。


反射例子

首先我们写一个反射的测试类小栗子,在此基础上通过反射获取对应的信息,代码如下

@MyAnnitation(name="someName",  value = "Hello World")
public  class Person{
    private String name="xm";
    public int age=18;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private void eat(){
        System.out.println("吃水果");
    }

    public void play(String playType){
        System.out.println(this.name+"玩"+playType);
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MyAnnitation {
    public String name();
    public String value();
}

1.获取class对象

类名.class
Class.forName(类名)

public static void ObtainClass() {
        //方式一
        Class personCls1 = Person.class;

        //方式二
        Class personCls2 = null;
        String clsName = "com.bridge.view.javademo.Person";//类全名=类所在包名+类名
        try {
            personCls2 = Class.forName(clsName);
        } catch (ClassNotFoundException e) {//如果forName未找类,则抛出次异常
            e.printStackTrace();
        }
        System.out.println("**获取class对象**");
        System.out.println("方式一:" + personCls1);
        System.out.println("方式二:" + personCls2);
        System.out.println("                         ");
        System.out.println("                         ");
}

输出结果:
**获取class对象**
方式一:class com.bridge.view.javademo.Person
方式二:class com.bridge.view.javademo.Person

2.获取类名

Class.getName()
Class.getSimpleName

    public static void ObtainClassName() {
        Class personCls = Person.class;
        System.out.println("**获取类名**");
        System.out.println("方式一:" + personCls.getName());//获取全名
        System.out.println("方式二:" + personCls.getSimpleName());//获取类名,不包含所在包名
        System.out.println("                         ");
        System.out.println("                         ");
    }

输出结果:
**获取类名**
方式一:com.bridge.view.javademo.Person
方式二:Person

3.获取字段

Class.getFields()
Class.getField()
Class.getDeclaredFields()
Class.getDeclaredField()

    public static void ObtainField() {
        Class personCls = Person.class;
        Field[] Fields;
        System.out.println("**获取字段**");
        //通过getFields 获取所有公开字段
        System.out.println("获取所有公开字段");
        Fields = personCls.getFields();//获取public公开字段
        for (int i = 0; i < Fields.length; i++) {
            System.out.println(Fields[i]);
        }

        //通过getField获取指定公开字段
        System.out.println("获取指定公开字段");
        try {
            Field field;
            field = personCls.getField("age");
            System.out.println(field);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
       //通过getDeclaredFields,获取所有字段
        System.out.println("获取所有字段");
        Fields = personCls.getDeclaredFields();//获取所有申明字段,包括public private proteced
        for (int i = 0; i < Fields.length; i++) {
            Fields[i].setAccessible(true);//打开访问限制,在这里不调用也可以访问,确保访问还是加上这行代码
            System.out.println(Fields[i]);
        }

        //通过getDeclaredField,获取所有字段
        System.out.println("获取指定所有字段");
        try {
            Field field;
            field = personCls.getDeclaredField("age");
            field.setAccessible(true);//打开访问限制,在这里不调用也可以访问,确保访问还是加上这行代码
            System.out.println( field);
            field = personCls.getDeclaredField("name");
            field.setAccessible(true);//打开访问限制,在这里不调用也可以访问,确保访问还是加上这行代码
            System.out.println( field);

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        System.out.println("                         ");
        System.out.println("                         ");
    }

输出结果:
**获取字段**
获取所有公开字段
public int com.bridge.view.javademo.Person.age
获取指定公开字段
public int com.bridge.view.javademo.Person.age
获取所有字段
private java.lang.String com.bridge.view.javademo.Person.name
public int com.bridge.view.javademo.Person.age
获取指定所有字段
public int com.bridge.view.javademo.Person.age
private java.lang.String com.bridge.view.javademo.Person.name

4.获取方法

Class.getMethods()
Class.getMethod()
Class.getDeclaredMethods()
Class.getDeclaredMethod

 public static void ObtainMethod() {
        Class personCls = Person.class;
        System.out.println("**获取方法**");
        //通过getMethods获取所有公开方法
        System.out.println("获取所有公开字段的方法");
        Method[] methods =  personCls.getMethods();
        for(int i=0;i<methods.length;i++){
            System.out.println(methods[i]);
        }

        //获取特定公开方法
        System.out.println("获取特定公开方法");
        try {
            Method method =  personCls.getMethod("play",new Class[]{String.class});
            System.out.println(method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //获取所有方法
        System.out.println("获取所有方法");
        methods = personCls.getDeclaredMethods();
        for(int i=0;i<methods.length;i++){
            System.out.println(methods[i]);
        }

        //获取特定公开方法
        System.out.println("获取所有特定方法");
        try {
            Method method =  personCls.getDeclaredMethod("eat");
            System.out.println(method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        System.out.println("                         ");
        System.out.println("                         ");
}

输出结果:
**获取方法**
获取所有公开字段的方法
public void com.bridge.view.javademo.Person.play(java.lang.String)
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()
获取特定公开方法
public void com.bridge.view.javademo.Person.play(java.lang.String)
获取所有方法
public void com.bridge.view.javademo.Person.play(java.lang.String)
private void com.bridge.view.javademo.Person.eat()
获取所有特定方法
private void com.bridge.view.javademo.Person.eat()

5.获取构造函数

    public static void ObtainConstructor() {
        Class personCls = Person.class;
        System.out.println("**获取构造函数**");
        Constructor[] constructors = personCls.getConstructors();
        System.out.println("获取所有的构造函数");
        for(int i=0;i<constructors.length;i++){
            System.out.println(constructors[i]);
        }

        System.out.println("获取特定的构造函数");
        try {
            Constructor constructor = personCls.getConstructor(new Class[]{String.class,int.class});
            System.out.println(constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        System.out.println("                         ");
        System.out.println("                         ");
    }

输出结果:
**获取构造函数**
获取所有的构造函数
public com.bridge.view.javademo.Person(java.lang.String,int)
获取特定的构造函数
public com.bridge.view.javademo.Person(java.lang.String,int)

6.获取注解

Class.getAnnotations()
Class.getAnnotation();
Class.getDeclaredAnnotations();

    public static void ObtainAnnotation() {
        Class personCls = Person.class;
        Annotation[] annotations = personCls.getAnnotations();
        for(int i=0;i<annotations.length;i++){
            if(annotations[i] instanceof MyAnnitation){
                System.out.println("annotation:"+annotations[i]);
                MyAnnitation myAnnitation = (MyAnnitation) annotations[i];
                System.out.println("name:"+myAnnitation.name());
                System.out.println("value:"+myAnnitation.value());
            }
        }
    }

输出结果:
annotation:@com.bridge.view.javademo.MyAnnitation(name=someName, value=HelloWorld)
name:someName
value:Hello World

参考

Java 反射机制教程

相关文章

  • java反射初探

    反射(Reflection)? 它是java语言特有的,其他语言并无此特性,其能力是在程序运行期间中,检查,操作,...

  • Java反射—初探反射基础

    Github:https://github.com/ilssio/java-base-ilss 1. 认识Clas...

  • Java 反射技术初探

    Java反射概述 Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的属性和方法;对于任意一个类,...

  • 博客地址

    java注解-01、java注解-02、Git面试资源java反射-01、java反射-02、java反射-03为...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 2016.10.12-java 反射机制的初探

    首先声明两个类 Word Excel 创建一个Test方法:做如下测试#######1.动态获取一个类的信息;包括...

网友评论

      本文标题:java反射初探

      本文链接:https://www.haomeiwen.com/subject/vzbkzttx.html