zoukankan      html  css  js  c++  java
  • java基础——反射常用操作

    首先定义一些类和接口

    package reflection1;
    
    public interface MtInterface {
        void info();
    }
    package reflection1;
    
    import java.io.Serializable;
    
    public class Creature<T> implements Serializable {
        private char gender;
        public double weight;
        
        
        
        public Creature() {
            super();
        }
        private void breath() {
            System.out.println("呼吸");
        }
        public void eat() {
            System.out.println("吃饭");
        }
    }
    package reflection1;
    
    
    public class Person extends Creature<String> implements Comparable<String>,MtInterface {
        
        private String name;
        int age;
        public int id;
        
        public Person() {
            super();
        }
        private Person(String name) {
            super();
            this.name = name;
        }
        Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public Person(String name, int age, int id) {
            super();
            this.name = name;
            this.age = age;
            this.id = id;
        }
        
        private String show(String nation) throws Exception{
            System.out.println("nation="+nation);
            return nation;
        }
        public String display(String interests) {
            return interests;
        }
        
        @Override
        public void info() {
            System.out.println("我是人");
        }
    
        @Override
        public int compareTo(String o) {
            return 0;
        }
        
        private static void showDesc() {
            System.out.println("static method");
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
        }
        
    }

    反射获取运行时类的属性

    package reflection2;
    
    import java.lang.reflect.Field;
    
    import org.junit.jupiter.api.Test;
    
    import reflection1.*;
    
    /*
     * 获取当前运行时类的属性结构
     * */
    
    public class FieldTest {
        @Test
        public void test1() {
            Class clazz = reflection1.Person.class;
            Field [] fields = null;
            
            //获取属性结构
            //getFields():获取当前运行时类及其父类中所有public的属性
            fields = clazz.getFields();
            for(Field f:fields)
                System.out.println(f);
            
            System.out.println("");
            
            //getDeclaredFields():获得当前运行时类的所有属性,不包含父类的属性,不考虑权限
            fields = clazz.getDeclaredFields();
            for(Field f:fields)
                System.out.println(f);
            
            System.out.println("");
        }
        
        //权限修饰符:数据类型 变量名
        @Test
        public void test2() {
            Class clazz = reflection1.Person.class;
            Field [] fields = clazz.getDeclaredFields();
            for(Field f:fields) {
                System.out.println(f);
                /*
                 *
                 * 1.权限修饰符
                 *  PUBLIC: 1
                    PRIVATE: 2
                    PROTECTED: 4
                    STATIC: 8
                    FINAL: 16
                    SYNCHRONIZED: 32
                    VOLATILE: 64
                    TRANSIENT: 128
                    NATIVE: 256
                    INTERFACE: 512
                    ABSTRACT: 1024
                    STRICT: 2048
                 * */
                int modifiers = f.getModifiers();
                System.out.println(modifiers);
                
                //2.数据类型
                Class type = f.getType();
                System.out.println(type);
                
                //3.变量名
                String name = f.getName();
                System.out.println(name);
                
                System.out.println("");
            }
        }
    }

    反射获得运行时类的方法

    package reflection2;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    
    import org.junit.jupiter.api.Test;
    
    import reflection1.Person;
    
    /*
     * 获取运行时类的方法结构
     * 
     * */
    
    public class MethodTest {
        @Test
        public void test1() {
            Class clazz = Person.class;
            //getMethods():获取当前类及其父类所有public方法
            Method[] methods = clazz.getMethods();
            for(Method m:methods) {
                System.out.println(m);
            }
            System.out.print('
    ');
            
            //获取当前运行时类中的所有方法
            methods = clazz.getDeclaredMethods();
            for(Method m:methods) {
                System.out.println(m);
            }
        }
        /*
         * 权限修饰符,返回值类型,方法名(参数类型1   参数1,参数类型2  参数2,参数类型3  参数3...)
         * */
        @Test
        public void test2() {
            //1.获取方法声明的注解
            Class clazz = Person.class;
            Method[]methods = clazz.getDeclaredMethods();
            for(Method m:methods) {
                System.out.println(m);
                //1.获得方法声明的注解
                Annotation[] annos = m.getAnnotations();
                for(Annotation a:annos) {
                    System.out.println("注解:"+a);
                }
                
                //2.获取权限修饰符
                int modifier = m.getModifiers();
                System.out.println("权限:"+modifier);
                
                //3.返回值类型
                System.out.println("返回值类型:"+m.getReturnType().getName());
                
                //4.方法名
                System.out.println("方法名字:"+m.getName());
                
                //5.形参列表
                Class [] parameterTypes = m.getParameterTypes();
                if(!(parameterTypes == null && parameterTypes.length==0)) {
                    System.out.println("形参列表:");
                    for(int i=0;i<parameterTypes.length;i++) {
                        Class p = parameterTypes[i];
                        System.out.println(p.getName()+" args_"+i);
                    }
                }
                
                //6.抛出的异常
                Class [] exceptionTypes = m.getExceptionTypes();
                for(Class e:exceptionTypes)
                    System.out.println("异常:"+e.getName());
                
                System.out.println("");
            }
        }
        
    }

    反射获得运行时类的构造器,父类,泛型信息,接口,包等信息

    package reflection2;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.params.ParameterizedTest;
    
    import reflection1.Person;
    
    public class OtherTest {
        /*
         * 获取构造器结构
         * */
        @Test
        public void test1() {
            Class clazz = Person.class;
            //获得public的构造器(无父类)
            Constructor[] constructors = clazz.getConstructors();
            for(Constructor c:constructors)
                System.out.println(c);
            
            System.out.println();
            
            //获得所有构造器
            constructors = clazz.getDeclaredConstructors();
            for(Constructor c:constructors)
                System.out.println(c);
        }
        /*
         * 获取运行时类的父类
         * */
        @Test
        public void test2() {
             Class clazz = Person.class;
             Class superClass = clazz.getSuperclass();
             System.out.println(superClass);
             
        }
        
        /*
         * 获取运行时带泛型的父类
         * */
        @Test
        public void test3() {
             Class clazz = Person.class;
             Type superClass = clazz.getGenericSuperclass();
             System.out.println(superClass);
             
        }
        /*
         * 获取运行时带泛型的父类的泛型
         * 关于ParameterizedType的理解
         *     https://www.jianshu.com/p/da21b3a59b47 定义
         *     https://www.jianshu.com/p/cfa74c980b25 理解
         * */
        @Test
        public void test4() {
             Class clazz = Person.class;
             Type superClass = clazz.getGenericSuperclass();
             ParameterizedType paramType = (ParameterizedType)superClass;
             //getActualTypeArguments()可以去掉最外面一层<>获得里面的Type数组
             Type[] types = paramType.getActualTypeArguments();
             System.out.println(types[0].getTypeName());
        }
        
        /*
         * 获取运行时类的接口
         * */
        @Test
        public void test5() {
            Class clazz = Person.class;
            Class[] interfaces = clazz.getInterfaces();
            for(Class c:interfaces)
                System.out.println(c);
            
            System.out.println();
            Class[] interfaces1 = clazz.getSuperclass().getInterfaces();
            for(Class c:interfaces1)
                System.out.println(c);
        }
        
        /*
         * 获取类运行时所在包
         * */
        @Test
        public void test6() {
            Class clazz = Person.class;
            Package package1 = clazz.getPackage();
            System.out.println(package1);
        }
    }

    反射调用运行时类的属性,方法,构造器(反射打破封装性)

    package reflection2;
    
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import org.junit.jupiter.api.Test;
    
    import reflection1.Person;
    
    /*
     * 调用运行时类中指定的结构:属性,方法,构造器
     * */
    
    public class ReflectionTest {
        
        /*
         * 反射调类属性
         * 
         * */
        @Test
        public void test1() 
                throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException 
        {
            Class clazz = Person.class;
            
            //创建运行时类对象
            Person person = (Person)clazz.newInstance();
            
            //获取指定变量名的属性
            Field name = clazz.getDeclaredField("name");
            
            //将该属性权限修改为可获得
            name.setAccessible(true);
            
            //设置当前对象的属性值:set()方法:参数1:指明设置哪个对象的属性,参数2:将属性设置为多少
            name.set(person, "Tom");
            
            /*
             * 获取当前属性值get():参数1:获取哪个对象的属性值
             * */
            Field age = clazz.getDeclaredField("age");
            age.setAccessible(true);
            int pAge = (int)age.get(person);
            System.out.println(pAge);
            
            name.setAccessible(false);//还要再改回去
        }
        
        /*
         * 操作运行时类中指定的方法
         * */
        @Test
        public void test2() 
                throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException 
        {
            Class clazz = Person.class;
            
            //创建运行时类对象
            Person person = (Person)clazz.newInstance();
            
            //获取指定的某个方法
            //参数1:指明获取方法的名称,参数2:指明获取方法的形参列表
            Method show = clazz.getDeclaredMethod("show", String.class);
            
            //将权限改为可访问
            show.setAccessible(true);
            
            //invoke():参数1:方法调用者 参数2:给方法形参赋值的实参
            //返回值 为调用的方法的返回值
            String nation = (String)show.invoke(person,"CHN");
            System.out.println(nation);
            
            
            System.out.println("*********************调用静态方法**********************");
            //得到这个方法的步骤是一样的
            Method showDesc = clazz.getDeclaredMethod("showDesc");
            showDesc.setAccessible(true);
            //由于是静态,直接用这个类去调用就行
            showDesc.invoke(Person.class);
        }
        
        /*
         * 调用运行时类的指定的构造器
         * */
        @Test
        public void test3() 
                throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 
        {
            Class clazz = Person.class;
            
            //获取指定的构造器:参数:指明构造器的参数列表
            Constructor constructor = clazz.getDeclaredConstructor(String.class);
            
            //将权限改为可访问
            constructor.setAccessible(true);
            
            Person person = (Person)constructor.newInstance("Tom");
            System.out.println(person);
        }
        
    }
  • 相关阅读:
    leetcode教程系列——Binary Tree
    《Ranked List Loss for Deep Metric Learning》CVPR 2019
    《Domain Agnostic Learning with Disentangled Representations》ICML 2019
    Pytorch从0开始实现YOLO V3指南 part5——设计输入和输出的流程
    Pytorch从0开始实现YOLO V3指南 part4——置信度阈值和非极大值抑制
    Pytorch从0开始实现YOLO V3指南 part3——实现网络前向传播
    Pytorch从0开始实现YOLO V3指南 part2——搭建网络结构层
    Pytorch从0开始实现YOLO V3指南 part1——理解YOLO的工作
    让我佩服的人生 文章
    win8.1配置cordova+ionic等一系列东西
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12156958.html
Copyright © 2011-2022 走看看