java反射系列五之获取类的完整结构

Posted 静心*尽力

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java反射系列五之获取类的完整结构相关的知识,希望对你有一定的参考价值。

 

代码示例

Person类

package reflect;

@MyAnnotation(value = "guozi")
public class Person extends Creature<String> implements Comparable,MyInterface{
    public String name;
    private int age;
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    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;
    }
    @MyAnnotation(value = "123")
    public void show() {
        System.out.println("我是巫妖果子");
    }
    private void display(String nation) throws Exception{
        System.out.println("我的国籍是: "+nation);
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    @Override
    public int compareTo(Object o) {
        // TODO Auto-generated method stub
        return 0;
    }
    class Bird{
        
    }
}

Person的父类

package reflect;

public class Creature<T> {
    public double weight;
    
    public void breath() {
        System.out.println("呼吸!");
    }
}

Person实现的接口

package reflect;

import java.io.Serializable;

public interface MyInterface extends Serializable{

}

注释

package reflect;

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

有了这些"复杂"条件,我们可以:

获取属性  属性类型  属性修饰权限

package reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class TestFiled {
    public static void main(String[] args) {
        TestFiled t = new TestFiled();
        t.test();
        t.test1();
    }
    public void test() {
        Class clazz = Person.class;
        //1.getFields():只能获取到运行时类中及其父类中声明为public的属性
        Field[] fields = clazz.getFields();
        for(int i= 0; i<fields.length; i++) {
            System.out.println(fields[i]);
        }
        System.out.println();
        //2.getDeclareFields():获取运行时类本身声明的所有属性
        Field [] fields1 = clazz.getDeclaredFields();
        for(Field f:fields1) {
            System.out.println(f.getName());
        }
    }
    //获取对应的运行时类的属性
    public void test1() {
        Class clazz = Person.class;
        //得到运行时类的声明属性
        Field [] fields1 = clazz.getDeclaredFields();
        for(Field f:fields1) {
            //1.获取每个属性的权限修饰符
            //0代表default修饰符  1代表public修饰符   2 代表private修饰符
            int i = f.getModifiers();
            //将代表修饰符的数字转化成字符
            String str1 = Modifier.toString(i);
            System.out.print(str1+" ");
            //2.获取属性的类型
            Class type = f.getType();
            System.out.print(type.getName()+" ");
            //3.获取属性名
            System.out.println(f.getName());
        }
    }
}

可以获取注解  权限修饰符 返回值类型 方法名 形参列表 异常
package reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class TestMethod {
    public static void main(String[] args) {
        TestMethod t = new TestMethod();
        //t.test();
        t.test1();
    }
    public void test() {
        //1.getMethods():获取运行时类及其父类中所有的声明为public的方法
        Class clazz = Person.class;
        Method [] m1 = clazz.getMethods();
        for(Method m : m1) {
            System.out.println(m);
        }
        System.out.println();
        //2.getDeclaredMethods():获取运行时类本身声明的所有方法
        Method[] m2 = clazz.getDeclaredMethods();
        for(Method m : m2) {
            System.out.println(m);
        }
    }
    //注解  权限修饰符 返回值类型 方法名 形参列表 异常
    public void test1() {
        Class clazz = Person.class;
        
        Method [] m2 = clazz.getDeclaredMethods();
        for(Method m : m2) {
            //1.注解
            Annotation [] ann = m.getAnnotations();
            for(Annotation a : ann) {
                System.out.print(a);
            }
        //2.权限修饰符
            String str = Modifier.toString(m.getModifiers());
            System.out.print(str+" ");
        //3.返回值类型
            Class returnType = m.getReturnType();
            System.out.print(returnType.getName()+" ");
        //4.方法名
            System.out.print(m.getName()+" ");
        //5.形参列表
            System.out.print("(");
            Class [] params = m.getParameterTypes();
            for(int i = 0;i<params.length;i++) {
                System.out.print(params[i].getName()+" args"+i+" ");
            }
            System.out.print(")");
        //6.异常类型
         Class [] exps = m.getExceptionTypes();
         if(exps.length !=0) {
             System.out.print("throws ");
         }
         for(int i = 0;i<exps.length;i++) {
             System.out.print(exps[i].getName()+ " ");
         }
          System.out.println();
        }
    }
}

 获取继承的父类  带泛型的父类  父类的泛型  实现的接口  所在的包  注解

package reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class TestOther {
    public static void main(String[] args) {
        TestOther t = new TestOther();
        t.test();
    }
    public void test() {
        //1.获取运行时类的父类
        Class clazz = Person.class;
        Class superClass = clazz.getSuperclass();
        System.out.println(superClass);
        
        //2.获得运行时类的带泛型的父类
        Type type1 = clazz.getGenericSuperclass();
        System.out.println(type1);
        
        //3.获取父类的泛型
        Type type2 = clazz.getGenericSuperclass();
        ParameterizedType param = (ParameterizedType)type2;
        Type [] ars = param.getActualTypeArguments();
        System.out.println(((Class)ars[0]).getName());
        
        //4.获取实现的接口
        //获取不到接口的父类接口
        Class [] interfaces=clazz.getInterfaces();
        for(Class c : interfaces) {
            System.out.println(c);
        }
        
        //5.获取所在的包
        Package pack = clazz.getPackage();
        System.out.println(pack);
        
        //6.获取注解
        Annotation [] anns = clazz.getAnnotations();
        for(Annotation a : anns) {
            System.out.println(a);
        }
    }
}

 

以上是关于java反射系列五之获取类的完整结构的主要内容,如果未能解决你的问题,请参考以下文章

大数据必学Java基础(九十):通过反射获取运行时类的完整结构

31反射(获取Class实例剖析运行时类的完整结构读取properties文件反射创建类越过泛型检查)枚举

包子学系列——Java基础第十五章_Java反射机制

通过反射来获取对应运行时类的完整结构

Java基础-反射

Java基础-反射