前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >反射入门_入门教程

反射入门_入门教程

作者头像
全栈程序员站长
发布2022-09-21 08:27:19
2330
发布2022-09-21 08:27:19
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

反射

代码语言:javascript
复制
package com.atguigu.java;

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

public class Person { 
   
    private String name;
    public int age;

    public Person() { 
   
    }

    public void setName(String name) { 
   
        this.name = name;
    }

    @Override
    public String toString() { 
   
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    public String getName() { 
   
        return name;
    }

    public int getAge() { 
   
        return age;
    }

    public Person(String name, int age) { 
   
        this.name = name;
        this.age = age;
    }
    private Person(String name) { 
   
        this.name = name;
    }
    public void show(){ 
   
        System.out.println("您好,我是一个人");
    }
    private String showNation(String nation){ 
   
        System.out.println("我的国籍是" + nation);
        return nation;
    }

    public static void main(String[] args) throws Exception { 
   
        Class clazz = Person.class;
// 1.通过反射创建对象
        Constructor cons = clazz.getConstructor(String.class,int.class);
        Object obj = cons.newInstance("Tom",12);
        Person p = (Person) obj;
        System.out.println(obj.toString());


// 2.通过反射,使用对象指定的方法和属性
        Field age = clazz.getDeclaredField("age");
        age.set(person,10);
        System.out.println(p.toString());

// 3.调用方法
        Method show = clazz.getMethod("show");
        show.invoke(p);
    }
}

通过反射可以调用私有的构造器和方法

代码语言:javascript
复制
public static void main(String[] args) throws Exception { 
   
        //私有属性
        Class clazz = Person.class;
        Constructor cons1 = clazz.getDeclaredConstructor(String.class);
        cons1.setAccessible(true);
        Person p = (Person) cons1.newInstance("Jerry");
        System.out.println(p);
        //私有方法
        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        String nation = (String) showNation.invoke(p,"中国");
        System.out.println(nation);

    }

Class类的理解

  1. 类的加载过程:程序经过javac命令后会生成一个或多个.class文件。java命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中。加载到内存中的类。我们就成为运行时类,此运行时类,就作为一个Class的一个实例。
  2. Class类对应一个运行时类。

Class实例的获取(4种)

代码语言:javascript
复制
public static void main(String[] args) throws Exception { 
   
// 1.
        Class clazz1 = Person.class;
        System.out.println(clazz1);

// 2.
        Person p1 = new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);

// 3.
        Class clazz3 = Class.forName("com.atguigu.java.Person");
        System.out.println(clazz3);

// 4.
        ClassLoader classLoader = Person.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("com.atguigu.java");
        System.out.println(clazz4);
    }

类(外部类,内部类,匿名内部类等等),接口,数组,enum,注解,基本数据类型 ,void都算Class对象

3种类加载器

  1. 引导类加载器:负责java核心类库的加载,无法获得.
  2. 扩展类加载器:负责jre/lib/text目录下的类的加载
  3. 系统类加载器:自定义的类的加载器,也是最常用的加载器

使用类加载器读取配置文件

代码语言:javascript
复制
public static void main(String[] args) throws Exception { 
   
        Properties pros = new Properties();
        ClassLoader classLoader = Person.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("jdbc.properties");
        pros.load(is);
        String user = pros.getProperty("user");
        System.out.println(user);
    }

获取运行时类的完整结构

1. 属性
代码语言:javascript
复制
public static void main(String[] args) { 
   
        Class clazz = Person.class;
        //获取当前类和其父类的所生命的public属性
        Field[] fields = clazz.getFields();
        for(Field field : fields){ 
   
            System.out.println(field);
        }
        //获取当前运行时类的所有属性,不包含父类。
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f :declaredFields){ 
   
            System.out.println(f);
        }
        //权限修饰符 数据变量 变量名
        Field[] declaredFields1 = clazz.getDeclaredFields();
        for (Field f : declaredFields1){ 
   
            //1.权限修饰符
            int modifier = f.getModifiers();
            System.out.println(Modifier.toString(modifier));
            //2.数据类型
            Class type = f.getType();
            System.out.println(type.getName());
            //变量名
            System.out.println(f.getName());

        }
    }
2. 方法
代码语言:javascript
复制
public static void main(String[] args) { 
   
        //当前类和其父类所有的public方法
        Class clazz = Person.class;
        Method[] methods = clazz.getMethods();
        for(Method m : methods){ 
   
            System.out.println(m);
        }

        System.out.println();

        //获取当前类所声明的所有方法:
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m : declaredMethods){ 
   
            System.out.println(m);
        }
    }
3. 注解
代码语言:javascript
复制
public static void main(String[] args) { 
   
        Class clazz = Person.class;
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m : declaredMethods){ 
   
            //获取方法的注解
            Annotation[] annos = m.getAnnotations();
            for(Annotation a : annos){ 
   
                System.out.println(a);
            }
            //权限修饰符
            System.out.print(Modifier.toString(m.getModifiers()) + "\t");
            //返回值类型
            System.out.print(m.getReturnType().getName() + "\t");
            //方法名
            System.out.print(m.getName());
            System.out.print("(");
            //形参列表
            Class[] parameterTypes = m.getParameterTypes();
            if(!(parameterTypes == null && parameterTypes.length != 0))
            { 
   
                for(int i = 0;i < parameterTypes.length;i ++){ 
   
                    if(i == parameterTypes.length - 1){ 
   

                        System.out.print(parameterTypes[i].getName() + " args_" + i );
                    }
                    System.out.print(parameterTypes[i].getName() + " args_" + i + " , ");
                }
            }
            System.out.print(")");
            //抛出异常
            Class[] exceptionTypes = m.getExceptionTypes();
            if(!(exceptionTypes == null || exceptionTypes.length == 0)){ 
   
                System.out.print(" throus ");
                for(int i = 0;i < exceptionTypes.length;i ++) { 
   
                    if (i == exceptionTypes.length - 1) { 
   
                        System.out.print(exceptionTypes[i].getName());
                        break;
                    }
                    System.out.print(exceptionTypes[i].getName() + " , ");

                }

            }
            System.out.println();
        }

    }

4.构造器

代码语言:javascript
复制
public static void main(String[] args) throws Exception { 
   
        Class clazz = Person.class;
        //当前运行时类中声明为public构造器
        Constructor[] constructors = clazz.getConstructors();
        for(Constructor c : constructors){ 
   
            System.out.println(c);
        }
        System.out.println();
        //获取当前运行时类中声明的所有构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for(Constructor c : declaredConstructors){ 
   
            System.out.println(c);
        }
    }

5.泛型接口

代码语言:javascript
复制
public static void main(String[] args) throws Exception { 
   
        Class clazz = Person.class;
        Type genericSuperclass = clazz.getGenericSuperclass();
        System.out.println(genericSuperclass);


        Type genericSuperclass1 = clazz.getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) genericSuperclass1;
        //获取泛型类型
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        System.out.println(((Class)actualTypeArguments[0]).getName());



    }

6.接口,包,注解

代码语言:javascript
复制
public static void main(String[] args) throws Exception { 
   
        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);
        }
        //运行时类所在包
        Package pack = clazz.getPackage();
        //运行时类的注解
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annos : annotations){ 
   
            System.out.println(annos);
        }
    }

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168826.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 反射
    • Class类的理解
      • Class实例的获取(4种)
        • 3种类加载器
          • 使用类加载器读取配置文件
            • 获取运行时类的完整结构
              • 4.构造器
                • 5.泛型接口
                  • 6.接口,包,注解
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档