美文网首页
关于java反射的相关知识点

关于java反射的相关知识点

作者: yunqing_71 | 来源:发表于2019-06-11 09:34 被阅读0次

https://blog.csdn.net/hasser1/article/details/79384283

https://blog.csdn.net/hasser1/article/details/78699988

https://blog.csdn.net/xiaohanluo/article/details/52034127

上面都是别人家的知识点,下面总结自己家的知识点

反射的常见用法有三种:
1.查看:查看某个类的属性、方法、构造函数等
2.装载:装载指定的类到内存中
3.调用:通过输入参数调用指定的方法

下面看一个例子,查看属性、构造函数、方法等

@NoArgsConstructor
@AllArgsConstructor
class Dog{
    private int id;
    private String name;
    final protected int age = 1;

    //构造函数通过lombok注解声明

    //私有方法
    private void f1(){}
    //保护类型方法
    protected int f2(int i) {
        return 0;
    }
    //公有方法
    public String f3(String s) {
        return "java反射查看类的内容";
    }

}



public class MallTestApplicationTests {

    @Test
    public void test() {
        Class<Dog> clazz = Dog.class;
        //获取这个类所有的属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //输出修饰符
            System.out.print(Modifier.toString(field.getModifiers()) + "\t");
            //输出属性类型
            System.out.print(field.getGenericType().toString() + "\t");
            //输出属性名称
            System.out.println(field.getName());
        }
        System.out.println("----------------------------");
        //获取所有的方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("----------------------------------");
        //得到所有的构造函数
        Constructor[] constructors = clazz.getDeclaredConstructors();
        //输出所有构造函数
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }


    }

}


//输出结果
private int id
private class java.lang.String  name
protected final int age
----------------------------
public java.lang.String com.macro.mall.test.Dog.f3(java.lang.String)
private void com.macro.mall.test.Dog.f1()
protected int com.macro.mall.test.Dog.f2(int)
----------------------------------
public com.macro.mall.test.Dog(int,java.lang.String)
public com.macro.mall.test.Dog()

在实际项目中,我们不仅应该会“查看”累的属性、方法,在更多情况下,还需要通过反射装载调用类中的方法

通过forName和newInstance方法加载类

Class.forName("com.mysql.jdbc.Driver");

这个用法我们都不陌生,jdbc连接数据库时候装载数据库驱动的代码,那这个forName的作用是装载类吗?
额!既然这么问了,答案是肯定的,不是!!!

Class.forName的作用是返回一个Class类型的对象,他一般会与newInstance方法配套使用,newInstance方法的作用才是加载类。

@Test
    public void test1() {
        try {
            //获取Class类型的对象
            Class<?> clazz = Class.forName("Dog");
            //加载一个Dog类型的对象
            Dog dog = (Dog) clazz.newInstance();
            //调用Dog类型的方法
            dog.f3("111");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

newInstance是通过java虚拟机的类加载机制把指定的类加载到内存中的。

通过反射机制调用类的方法

class Person{
    private String name;
    //构造函数
    public Person(String name){
        this.name = name;
    }

    public void say(String language){
        System.out.println("我的名字是:" + name + "我的开发语言是:" + language);
    }

    public int add(int value) {
        return value + 100;
    }
}

@Test
    public void test3() {
        Class clazz = null;
        Constructor constructor = null;
        /**
         * 通过反射调用类的构造函数创建对象
         * 再用对象调用方法
         */
        try {
            //得到一个Class类型的对象,包含Person类的信息
            clazz = Class.forName("com.macro.mall.test.Person");
            //输入String.class得到Person类带参数的构造函数
            constructor = clazz.getDeclaredConstructor(String.class);
            //通过带参数的构造函数创建一个Person对象
            Person person = (Person) constructor.newInstance("Tom");
            //调用say()方法
            person.say("java");

            //通过clazz的getMethod()方法得到了带参say()方法的Method类型对象
            Method method1 = clazz.getMethod("say", String.class);
            //通过Method的invoke()调用say()方法,第一个参数指定say()方法由那个对象调用,第二个参数传入了该方法的参数
            method1.invoke(person, "Python");

            //通过clazz的getMethod()方法得到了带参add()方法的Method类型对象
            Method method2 = clazz.getMethod("add", int.class);
            //通过Method的invoke()调用add()方法,第一个参数指定add()方法由那个对象调用,第二个参数传入了该方法的参数
            Object obj = method2.invoke(person, 100);
            System.out.println(obj);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

输出结果:

我的名字是:Tom我的开发语言是:java
我的名字是:Tom我的开发语言是:Python
200

相关文章

网友评论

      本文标题:关于java反射的相关知识点

      本文链接:https://www.haomeiwen.com/subject/jdhffctx.html