【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);
    }
}

类加载器

【java】反射基础_第1张图片

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.ClassLoaders A 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.ClassLoaders AppClassLoader@2437c6dcjdk.internal.loader.ClassLoadersPlatformClassLoader@49e4cb85
null
null
BootstarpClassLoader是C++编写的,我们在Java中是获取不到的

你可能感兴趣的:(java,java,jvm,开发语言)