020.Java的反射机制

定义

JAVA反射机制是在运行状态中, 对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意方法和属性; 这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。


应用场景

Jdbc 加载驱动----- Spring ioc 框架


获取类的三种方式

package cn.qbz.thread;

public class Test112003 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Class.forName("cn.qbz.thread.Test112002");
        System.out.println(c1);

        Class c2 = Test112002.class;
        System.out.println(c2);

        Test112002 test112002 = new Test112002();
        Class c3 = test112002.getClass();
        System.out.println(c3);
    }
}

创建对象的两种方式

package cn.qbz.thread;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test112003 {
    public static void main(String[] args) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException,
            NoSuchMethodException, InvocationTargetException {
        //通过无参构造器构造创建对象
        Class c1 = Class.forName("cn.qbz.thread.User");
        User user = (User) c1.newInstance();
        user.setName("xiaoMing");
        System.out.println(user.getName());

        //通过有参构造器创建对象
        Constructor constructor = c1.getConstructor(String.class, String.class);
        User user2 = (User) constructor.newInstance("xiaoWang", "http://xiaowang.cn");
        System.out.println("name:" + user2.getName() + "\t" + "url:" + user2.getUrl());
    }
}

class User {
    private String name;
    private String url;

    public User() {
    }

    public User(String name, String url) {
        this.name = name;
        this.url = url;
    }

    public String getName() {
        return name;
    }

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

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

常用API

方法名称

作用

getDeclaredMethods []

获取该类的所有方法

getReturnType()

获取该类的返回值

getParameterTypes()

获取传入参数

getDeclaredFields()

获取该类的所有字段

setAccessible

允许访问私有成员

package cn.qbz.thread;

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

public class Test112003 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        Class usr = Class.forName("cn.qbz.thread.User");
        //获取所有属性
        Field[] fields = usr.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("属性:" + field.getName());
        }

        //获取所有方法
        Method[] methods = usr.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("method:" + method.getName());
        }

        //初始化对象
        User user = (User) usr.newInstance();
        //使用反射赋值属性
        Field fieldName = usr.getDeclaredField("name");
        // 标记为true 允许反射赋值
        fieldName.setAccessible(true);
        fieldName.set(user, "xiaoMing");

        System.out.println("usr.name:" + user.getName());

    }
}

class User {
    private String name;
    private String url;

    public User() {
    }

    public String getName() {
        return name;
    }

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

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

JDBC反射加载驱动

public class DemoJDBC {
    public static void main(String[] args) throws Exception {
        // 加载驱动类
        Class.forName("com.mysql.jdbc.Driver");
    
        // 通过DriverManager获取数据库连接
        String url = "jdbc:mysql://192.168.1.150/test";
        String user = "teamtalk";
        String password = "123456";
        Connection connection = (Connection) DriverManager.getConnection(
                url, user, password);
        
        PreparedStatement statement = (PreparedStatement) connection.prepareStatement(
                "insert persion (name, age) value (?, ?)");
        statement.setString(1, "hdu");
        statement.setInt(2, 21);
        statement.executeUpdate();
        
        ResultSet resultSet = statement.executeQuery("select * from persion");
        // 操作ResultSet结果集
        while (resultSet.next()) {
            // 第一种获取字段方式
            System.out.println(resultSet.getString(1) + " " + 
                    resultSet.getString(2) + " " + resultSet.getString(3));
        }

        // 关闭数据库连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

禁止使用反射机制初始化

  • 将构造函数为私有化

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏算法修养

PAT 甲级 1060 Are They Equal

1060. Are They Equal (25) 时间限制 50 ms 内存限制 65536 kB 代码长度限制 16000 B ...

32150
来自专栏Spring相关

第12章—使用NoSQL数据库—使用MongoDB+Jpa操作数据库

SpringData还提供了对多种NoSQL数据库的支持,包括MongoDB;neo4j和redis.他不仅支持自动化的repository,还支持基于模板的数...

11920
来自专栏Coding迪斯尼

java开发编译器:把C语言的循环指令编译成java字节码

20030
来自专栏软件开发

JavaSE学习总结(八)—— 异常处理(Exception)

一、理解异常及异常处理的概念 异常就是在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。 异常不是错误 程序中关键的位置有异常处理,提高程序的稳定...

23490
来自专栏软件开发 -- 分享 互助 成长

C++ string类的学习

string类对于处理字符串的一些应用非常的方便,我个人感觉,string和字符数组const char *很像,而且又比字符数组用起来方便的多。 注意其删除,...

44490
来自专栏GreenLeaves

C# 装箱和拆箱

C#的值类型可以分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型。 1、那么值类型和引用类型能否相互转换呢? 答案是肯定的,C#通过装箱和拆箱来实现两者...

200100
来自专栏有趣的django

第二章、深入类和对象

22700
来自专栏Java进阶之路

Java8 Optional 的正确使用方式

20300
来自专栏数据结构与算法

BZOJ3671: [Noi2014]随机数生成器(贪心)

第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子。第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N...

8620
来自专栏Hongten

java中的移位运算符:<<,>>,>>>总结

value >>> num     --   num 指定要移位值value 移动的位数。

22950

扫码关注云+社区

领取腾讯云代金券