【java】反射基础

简介: 【java】反射基础

Class类

import java.io.*;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<String> clazz = String.class;   //使用class关键字,通过类名获取
        Class<?> clazz2 = Class.forName("java.lang.String");
        //使用Class类静态方法forName(),通过包名.类名获取,注意返回值是Class<?>
        String c=new String("coleak");
        Class<?> clazz3 = c.getClass();  //通过实例对象获取
        System.out.println(clazz);
    }
}

class java.lang.String

Class类也是一个泛型类,只有第一种方法,能够直接获取到对应类型的Class对象,而以下两种方法使用了?通配符作为返回值,但是实际上都和第一个返回的是同一个对象

即:在JVM中每个类始终只存在一个Class对象,无论通过什么方法获取,都是一样的

public class Main {
    public static void main(String[] args) {
        Class<String[]> clazz = String[].class;
        System.out.println(clazz.getName());  //获取类名称(得到的是包名+类名的完整名称)
        System.out.println(clazz.getSimpleName());
        System.out.println(clazz.getTypeName());
        System.out.println(clazz.getClassLoader());   //获取它的类加载器
    }
}

Class对象与多态

import java.lang.reflect.Type;
public class Main {
    public static void main(String[] args) {
        String str = "";
        System.out.println(str.getClass());
        System.out.println(str instanceof String);
        System.out.println(str.getClass() == String.class);   //直接判断是否为这个类型
        Integer i = 10;
        System.out.println(i.getClass().asSubclass(Number.class));   //当Integer不是Number的子类时,会产生异常
        System.out.println(i.getClass().getSuperclass());
        Type type = i.getClass().getGenericSuperclass();
        //getGenericSuperclass()获取父类的原始类型
        System.out.println(type);
        System.out.println(type instanceof Class);
    }
    }

class java.lang.String

true

true

class java.lang.Integer

class java.lang.Number

class java.lang.Number

true

创建类对象

无参构造

public class Main {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException
    {
        Class<Student> clazz = Student.class;
        Student student = clazz.newInstance();
        student.test();
    }
    static class Student{
        public void test(){
            System.out.println("coleak");
        }
    }
    }

构造器

import java.lang.reflect.InvocationTargetException;
public class Main {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> clazz = Student.class;
        Student student = clazz.getConstructor(String.class).newInstance("coleak");
        student.test();
    }
    static class Student{
        public Student(String str){}
        public void test(){
            System.out.println("cc");
        }
    }
    }

非public权限

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Main {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> clazz = Student.class;
        Constructor<Student> constructor = clazz.getDeclaredConstructor(String.class);
        constructor.setAccessible(true);   //修改访问权限
        Student student = constructor.newInstance("coleak");
        student.test();
    }
    static class Student{
        private final String name;
        private Student(String str){
            this.name=str;
        }
        public void test(){
            System.out.println(name);
        }
    }
    }

调用类方法

public权限

import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();   //创建出学生对象
        Method method = clazz.getMethod("test", String.class);   
        //通过方法名和形参类型获取类中的方法
        method.invoke(instance, "coleak");   
        //通过Method对象的invoke方法来调用方法
    }
    }

非public权限

package com.test;
public class Student {
    private void test(String str){
        System.out.println("coleak"+str);
    }
}
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();   //创建出学生对象
        Method method = clazz.getDeclaredMethod("test", String.class);   
        //通过方法名和形参类型获取类中的方法
        method.setAccessible(true);
        method.invoke(instance, "coleak");   //通过Method对象的invoke方法来调用方法
    }
    }
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Method method = clazz.getDeclaredMethod("test", String.class);   //通过方法名和形参类型获取类中的方法
        System.out.println(method.getName());   //获取方法名称
        System.out.println(method.getReturnType());   //获取返回值类型
    }
}
//方法的参数为可变参数时
Method method = clazz.getDeclaredMethod("test", String[].class);

可以直接通过Method对象来获取这些信息

修改类的属性

public权限

package com.test;
public class Student {
    public int i;
    public void test(){
        System.out.println("coleak"+i);
    }
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();
        Field field = clazz.getField("i");   //获取类的成员字段i
        field.set(instance, 100);   //将类实例instance的成员字段i设置为100
        Method method = clazz.getMethod("test");
        method.invoke(instance);
    }
}

非public权限

import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Class<?> clazz = Class.forName("com.test.Student");
        Object instance = clazz.newInstance();
        Field field = clazz.getDeclaredField("i");   //获取类的成员字段i
        field.setAccessible(true);
        field.set(instance, 100);   //将类实例instance的成员字段i设置为100
        Method method = clazz.getMethod("test");
        method.invoke(instance);
    }
}

类加载器

public class Main {
    public static void main(String[] args) {
        System.out.println(Main.class.getClassLoader());   //查看当前类的类加载器
        System.out.println(Main.class.getClassLoader().getParent());  //父加载器
        System.out.println(Main.class.getClassLoader().getParent().getParent());  //爷爷加载器
        System.out.println(String.class.getClassLoader());   //String类的加载器
    }
}

jdk.internal.loader.ClassLoadersA p p C l a s s L o a d e r @ 2437 c 6 d c j d k . i n t e r n a l . l o a d e r . C l a s s L o a d e r s AppClassLoader@2437c6dc jdk.internal.loader.ClassLoadersAppClassLoader@2437c6dcjdk.internal.loader.ClassLoadersPlatformClassLoader@49e4cb85

null

null

BootstarpClassLoader是C++编写的,我们在Java中是获取不到的

目录
相关文章
|
4天前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
1月前
|
监控 Java
Java基础——反射
本文介绍了Java反射机制的基本概念和使用方法,包括`Class`类的使用、动态加载类、获取方法和成员变量信息、方法反射操作、以及通过反射了解集合泛型的本质。同时,文章还探讨了动态代理的概念及其应用,通过实例展示了如何利用动态代理实现面向切面编程(AOP),例如为方法执行添加性能监控。
|
1月前
|
Java
Java的反射
Java的反射。
33 2
|
2月前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
39 0
[Java]反射
|
3月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
78 9
Java——反射&枚举
|
2月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
32 2
|
3月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
|
2月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
25 0
|
3月前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
3月前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)