【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中是获取不到的

目录
相关文章
|
2月前
|
网络协议 算法 Java
|
7天前
|
Java C++
Java反射的简单使用
Java反射的简单使用
20 3
|
16天前
|
Java
【专栏】Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性
【4月更文挑战第27天】本文探讨了Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性。反射通过Class、Constructor、Method和Field类实现。文中列举了反射的应用场景,如动态创建对象、调用方法、访问属性和处理注解,并提供了相关实例代码演示。
|
7天前
|
SQL 存储 Java
【Java反射详解】
【Java反射详解】
11 1
|
11天前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
32 2
|
15天前
|
Java 测试技术
滚雪球学Java(24):Java反射
【4月更文挑战第13天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
21 0
滚雪球学Java(24):Java反射
|
19天前
|
Java
Java 反射
Java 反射
|
19天前
|
设计模式 Java 索引
由反射引出的Java动态代理与静态代理
由反射引出的Java动态代理与静态代理
15 0
|
19天前
|
存储 Java Shell
深入剖析Java中的反射,由浅入深,层层剥离!
深入剖析Java中的反射,由浅入深,层层剥离!
14 1
|
21天前
|
Java API Spring
Java基础教程(13)-Java中的反射和动态代理
【4月更文挑战第13天】Java反射机制允许程序在运行时获取类的信息并调用其方法。Class类是基础,提供获取类属性和方法的能力。通过Class对象,可以操作实例字段和方法,如getField、getDeclaredField等。动态代理是Java提供的创建接口实例的机制,其中JDK动态代理需目标类实现接口,而Cglib则可代理未实现接口的类。动态代理涉及Proxy和InvocationHandler接口。