反射的理解

public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //基本类型直接通过   基本类型。class就可以获得
        Class stringClass = String.class;
        Class integerClass = Integer.class;
        System.out.println("integerClass = " + integerClass);
        String name = stringClass.getName();
        System.out.println("name = " + name);
        String simpleName = stringClass.getSimpleName();
        System.out.println("simpleName = " + simpleName);
        String name1 = stringClass.getPackage().getName();
        System.out.println("name1 = " + name1);
        Package aPackage = stringClass.getPackage();
        System.out.println("aPackage = " + aPackage);
        Method[] methods = stringClass.getMethods();
        for (Method m:methods) {
            System.out.println("m = " + m);
        }
        Method[] declaredMethods = stringClass.getDeclaredMethods();
        for (Method md:declaredMethods) {
            System.out.println("md = " + md);
        }

        ClassLoader classLoader = stringClass.getClassLoader();
        System.out.println("classLoader = " + classLoader);
        System.out.println("stringClass = " + stringClass);
        //第二种方式是通过forName形式获得   里面传递的参数是包名+类名
        Class aClass = Class.forName("java.lang.String");
        System.out.println("aClass = " + aClass);

    }
}
public class ReflectDemo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            Person person=new Person("lisi",28);
        System.out.println("person = " + person);
             //通过构造器实例化对象
        String name="reflect.Person";
        Class aClass = Class.forName(name);
        System.out.println("aClass = " + aClass);
        Constructor constructor = aClass.getConstructor(String.class, int.class);
        Object lisi = constructor.newInstance("lisi", 30);
        System.out.println("lisi = " + lisi);
    }
}
public class ReflectDemo8 {
    public static void main(String[] args) throws URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Class reflectDemo8Class = ReflectDemo8.class;
        System.out.println("reflectDemo8Class = " + reflectDemo8Class);
        URL resource = reflectDemo8Class.getResource(".");
        System.out.println("resource = " + resource);
        URI uri = resource.toURI();
        System.out.println("uri = " + uri);
        File file1 = new File(uri);
        System.out.println("file1 = " + file1);
        File[] files = file1.listFiles();
        for (File file : files) {
            System.out.println("file = " + file);
            boolean b = file.getName().endsWith(".class");
            if(b){
                String name = file.getName();
                System.out.println("name = " + name);
                String substring = name.substring(0, name.indexOf("."));
                System.out.println("substring = " + substring);
                Class aClass = Class.forName(ReflectDemo8.class.getPackage().getName() + "." + substring);
                System.out.println("aClass = " + aClass);
                if(aClass.isAnnotationPresent(AutoRunClass.class)){
                    Object o = aClass.newInstance();
                    Method[] declaredMethods = aClass.getDeclaredMethods();
                    for(Method method : declaredMethods){
                        boolean annotationPresent = method.isAnnotationPresent(AutoRunMethod.class);
                        if(annotationPresent){
                            Object invoke = method.invoke(o);
                            System.out.println("invoke = " + invoke);
                        }
                    }
                }
            }
        }
    }

以上是代码的一个练习,下面是每一步应该做什么

反射是Java语言的一个重要特性,它允许程序在运行时动态地获取类的信息,包括类名、属性、方法、构造器等,可以使得程序更加灵活、易于扩展。下面是对Java反射的详细讲解和示例代码。

  1. 反射的基本概念

反射是指在程序运行时动态地获取一个类的信息,并且可以在运行时动态地创建对象、调用方法、获取属性等。Java反射的主要操作对象是Class类,也就是Java中的类对象。在Java中,所有的类都有一个Class类的对象,该对象包含了该类的所有信息,例如类名、属性、方法、构造器等,这些信息都可以利用反射来获取。

  1. 反射的常用操作

2.1 获取Class对象

在Java中,获取Class对象的方式有三种:

1)使用Class.forName()方法

该方法需要传入一个完整的类名,例如:

Class clazz = Class.forName("com.example.demo.User");

2)使用类的.class属性

该方式是最常用的方式,例如:

Class clazz = User.class;

3)使用对象的getClass()方法

该方法可以获取一个对象的Class对象,例如:

User user = new User();
Class clazz = user.getClass();

2.2 创建对象

在Java中,使用反射可以在运行时动态地创建对象,具体步骤如下:

1)获取Class对象

2)使用Class对象的newInstance()方法创建对象,例如:

Class clazz = Class.forName("com.example.demo.User");
User user = (User) clazz.newInstance();

2.3 调用方法

在Java中,使用反射可以在运行时动态地调用对象的方法,具体步骤如下:

1)获取Class对象

2)使用Class对象的getMethod()方法获取方法对象

3)使用Method对象的invoke()方法调用方法,例如:

Class clazz = Class.forName("com.example.demo.User");
User user = (User) clazz.newInstance();
Method method = clazz.getMethod("setName", String.class);
method.invoke(user, "Tom");

2.4 获取属性

在Java中,使用反射可以在运行时动态地获取对象的属性值,具体步骤如下:

1)获取Class对象

2)使用Class对象的getField()方法获取属性对象

3)使用Field对象的get()方法获取属性值,例如:

Class clazz = Class.forName("com.example.demo.User");
User user = (User) clazz.newInstance();
Field field = clazz.getField("name");
String name = (String) field.get(user);

下面是一个完整的示例代码,包括获取Class对象、创建对象、调用方法、获取属性等操作:

package com.example.demo;

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

public class ReflectionDemo {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获取Class对象的三种方式
        Class clazz = Class.forName("com.example.demo.User");
        Class clazz2 = User.class;
        User user = new User();
        Class clazz3 = user.getClass();

        //创建对象
        User user1 = (User) clazz.newInstance();

        //调用方法
        Method method = clazz.getMethod("setName", String.class);
        method.invoke(user1, "Tom");

        //获取属性
        Field field = clazz.getField("name");
        String name = (String) field.get(user1);
        System.out.println(name);
    }
}

package com.example.demo;

public class User {

    public String name;

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

下面是关于Java反射的重要知识点:

  1. 获取类型信息:Class类是Java反射的核心类,可以用来获取类、方法、属性等的详细信息。可以通过Class类的forName()方法、类名.class或对象.getClass()方法获取Class对象。

  2. 获取属性信息:可以使用Class类的getFields()、getDeclaredFields()、getField()和getDeclaredField()方法获取属性信息。

  3. 获取方法信息:可以使用Class类的getMethods()、getDeclaredMethods()、getMethod()和getDeclaredMethod()方法获取方法信息。

  4. 获取构造函数信息:可以使用Class类的getConstructors()、getDeclaredConstructors()和getConstructor()方法获取构造函数信息。

  5. 动态修改属性值:可以使用Field类的set()方法动态修改属性值。

  6. 动态调用方法:可以使用Method类的invoke()方法动态调用方法。

  7. 动态创建对象:可以使用Class类的newInstance()方法或Constructor类的newInstance()方法动态创建对象。

  8. 获取注解信息:可以使用Class类和Method类的getAnnotation()方法获取注解信息。

  9. 动态代理:可以使用Java动态代理实现动态代理对象。

  10. 性能问题:由于反射是动态的,所以会引入一些性能问题。需要在合适的时候使用反射,以避免性能问题。

你可能感兴趣的:(1024程序员节)