Java高级语法学习之反射详解

目录
  • 一、什么是反射
  • 二、准备测试:实体类的创建
  • 三、反射中的几个重要类及方法
    • (一)反射中的重要类之Class
    • (二)反射中的重要类之Field
    • (三)反射中的重要类之Constructor
    • (四)反射中的重要类之Method
  • 四、综合实战:利用反射机制编写对象拷贝工具类
    • (一)业务分析
    • (二)实体类准备
    • (三)工具类编写
  • 总结

一、什么是反射

java.lang包提供java语言程序设计的基础类,在lang包下存在一个子包:reflect,与反射相关的APIs均在此处;

官方对reflect包的介绍如下:

Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions.
The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.

java.lang.reflect官方介绍

简单来说,反射机制就像类对照平静的湖面,湖面映射出类的字段、方法、构造函数等信息;反射机制不仅可以看到类信息,还能针对字段、方法等做出相应的操作。

二、准备测试:实体类的创建

为方便解释说明,首先创建一个实体类,用于测试使用

package cn.byuan.entity;

/**
 * 学生实体类
 *
 * @author byuan
 * @date 2022-01-25
 */
public class Student {

    /**
     * 学生学号, 公共变量, 默认值: defaultStudentNo
     * */
    public String studentNo = "defaultStudentNo";

    /**
     * 学生姓名, 公共变量, 默认值: defaultStudentName
     * */
    public String studentName = "defaultStudentName";

    /**
     * 学生性别, 私有变量, 默认值: defaultStudentSex
     * */
    private String studentSex = "defaultStudentSex";

    /**
     * 学生年龄, 私有变量, 默认值: 0
     * */
    private Integer studentAge = 0;

    /**
     * 公有无参构造方法
     * */
    public Student() {

    }

    /**
     * 公有满参构造方法
     * */
    public Student(String studentNo, String studentName, String studentSex, Integer studentAge) {
        this.studentNo = studentNo;
        this.studentName = studentName;
        this.studentSex = studentSex;
        this.studentAge = studentAge;
    }

    /**
     * 私有构造方法
     * */
    private Student(String studentSex, Integer studentAge) {
        this.studentSex = studentSex;
        this.studentAge = studentAge;
    }

    /**
     * get/set 方法
     * */
    public String getStudentNo() {
        return studentNo;
    }

    public Student setStudentNo(String studentNo) {
        this.studentNo = studentNo;
        return this;
    }

    public String getStudentName() {
        return studentName;
    }

    public Student setStudentName(String studentName) {
        this.studentName = studentName;
        return this;
    }

    public String getStudentSex() {
        return studentSex;
    }

    public Student setStudentSex(String studentSex) {
        this.studentSex = studentSex;
        return this;
    }

    public Integer getStudentAge() {
        return studentAge;
    }

    public Student setStudentAge(Integer studentAge) {
        this.studentAge = studentAge;
        return this;
    }

    @Override
    public String toString() {
        return "Student{" +
                "studentNo = " + this.studentNo + ", " +
                "studentName = " + this.studentName + ", " +
                "studentSex = " + this.studentSex + ", " +
                "studentAge = " + this.studentAge +"}";
    }

    /**
     * 学生类说话方法
     * */
    private String speak(String message) {
        return this.studentName + " : " + message;
    }

}

三、反射中的几个重要类及方法

在了解反射前,先来梳理下一个类(Class)本身中包含了哪些内容。

  • 字段,字段又由修饰符、字段类型、字段名称、对应值等部分组成
  • 构造方法,构造方法可简单分为无参与有参两大类
  • 非构造方法,又称普通方法,方法由修饰符、返回值类型、方法名、形参表、方法体等部分构成

本文所论述的反射中几个重要类及其对应方法正基于以上内容

(一)反射中的重要类之Class

Class类代表了类本身,类本身包含字段,构造方法,非构造方法等内容,因此使用反射的第一步就是获取对象所对应的Class类。

仅就使用反射而言,我们需着重了解Class类的获取方式,下面给出实例

1. Class类测试实例

package cn.byuan.example;
import cn.byuan.entity.Student;
/**
 * 获取 Class 的几种方式
 *
 * @author byuan
 * @date 2022-01-25
 */
public class GetClassExample {
    public static void main(String[] args) throws ClassNotFoundException {
        // 获取 class 方式一: 通过类的全路径字符串获取 Class 对象
        Class getClassExample1 = Class.forName("cn.byuan.entity.Student");
        // 获取 class 方式二: 通过类名直接获取
        Class getClassExample2 = Student.class;
        // 获取 class 方式三: 通过已创建的对象获取对应 Class
        Student student1 = new Student();
        Class getClassExample3 = student1.getClass();
    }
}

(二)反射中的重要类之Field

Field类是对类中属性的描述,借助Class与Field的配合,我们可以了解类中有哪些字段,并做出相应处理;

1. Field类的获取与常用方法

Class类为我们提供了两个方法用以获取Field类:

  • getDeclaredFields():获取所有声明的字段(包括公有字段和私有字段)
  • getFields():仅可获取公有字段

Field类代表了类中的属性字段,常用类中属性字段可笼统分为两种,公有字段(public)与私有字段(private);

每个字段又具有四个属性:修饰符,字段类型,字段名称,对应值;Field也自然提供了对应方法对这四种属性进行获取:

  • getModifiers():获取字段修饰符相加值,想要获取明确标识需要通过Modifier常量的toString方法对相加值进行解码
  • getType():获取字段类型
  • getName():获取字段名称
  • get(Object):获取字段对应值

下面给出实例

2. Field类测试实例

package cn.byuan.example;

import cn.byuan.entity.Student;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * 获取类字段的几种方式
 *
 * @author byuan
 * @date 2021-01-25
 */
public class GetFieldExample {
    public static void main(String[] args) throws IllegalAccessException {
        Class studentClass = Student.class;
        // 获取类字段的两个方法: getDeclaredFields, getFields
        // 1. getDeclaredFields: 获取所有声明的字段(包括公有字段和私有字段)
        Field[] declaredFieldArray = studentClass.getDeclaredFields();
        printFieldInformation(declaredFieldArray);
        // 2. getFields: 仅可获取公有字段
        Field[] fieldArray = studentClass.getFields();
        printFieldInformation(fieldArray);
        // 获取字段对应值
        Student student = new Student()
                .setStudentSex("女")
                .setStudentAge(18);
        printFieldValue(student);
    }

    /**
     * 打印类字段信息
     *
     * @param fieldArray 类字段对象列表
     * */
    public static void printFieldInformation(Field[] fieldArray) {
        for (Field fieldPart : fieldArray) {
            System.out.println("直接打印类字段对象: " + fieldPart);
            // 获取字段修饰符
            String fieldModifier = Modifier.toString(fieldPart.getModifiers());
            // 获取字段类型
            String fieldType = fieldPart.getType().getName();
            // 获取字段名称
            String fieldName = fieldPart.getName();
            System.out.println(fieldModifier + " " + fieldType + " " + fieldName);
        }
        System.out.println();
    }

    /**
     * 打印类字段属性
     *
     * @param t 泛型对象
     * */
    private static <T> void printFieldValue(T t) throws IllegalAccessException {
        Field[] fieldValueArray = t
                .getClass()
                .getDeclaredFields();
        for (Field fieldValuePart : fieldValueArray) {
            // 对于有可能存在的 private 字段取消语言访问检查
            fieldValuePart.setAccessible(true);
            // 字段名称
            String filedName = fieldValuePart.getName();
            // 字段对应值
            String fieldValue = fieldValuePart.get(t).toString();
            System.out.println(filedName + " = " + fieldValue);
        }
    }
}

运行截图

(三)反射中的重要类之Constructor

Constructor代表了某个类的构造方法,是用来管理所有的构造函数的类

1. Constructor类的获取与常用方法

Class类为我们提供了两个方法用以获取Constructor类:

  1. getDeclaredConstructors():获取所有构造方法
  2. getConstructors():仅可获取公有构造方法

对于构造器,可简单将其分为两大类,无参构造器与带参构造器,构造器也是方法的一种,因此对于任意一构造器都由修饰符,方法名,形参表,方法体四部分组成;Constructor自然也为其组成部分提供了对应方法:

  1. 与字段类似,Constructors同样提供了getModifiers()方法:获取构造器修饰符相加值,想要获取明确标识需要通过Modifier常量的toString方法进行解码
  2. getName():获取构造器名称
  3. getParameterTypes():获取构造器参数列表

下面给出实例

2. Constructor类测试实例

package cn.byuan.example;
import cn.byuan.entity.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

/**
 * 获取构造方法的几种方式
 *
 * @author byuan
 * @date 2022-01-25
 */
public class GetConstructorsExample {
    public static void main(String[] args) {
        Class studentClass = Student.class;
        // 获取类构造器的两个方法: getDeclaredConstructors, getConstructors
        // 1. getDeclaredConstructors: 获取所有构造方法
        Constructor[] declaredConstructorArray = studentClass.getDeclaredConstructors();
        printConstructorInformation(declaredConstructorArray);
        // 2. getConstructors, 仅可获取公有构造方法
        Constructor[] constructorArray = studentClass.getConstructors();
        printConstructorInformation(constructorArray);
    }

    /**
     * 打印构造器信息
     *
     * @param constructorArray 构造器对象列表
     * */
    public static void printConstructorInformation(Constructor[] constructorArray) {
        for (Constructor constructorPart : constructorArray) {
            System.out.println("直接打印构造器对象: " + constructorPart);
            // 获取构造器修饰符
            String constructorModifier = Modifier.toString(constructorPart.getModifiers());
            // 获取构造器名称
            String constructorName = constructorPart.getName();
            // 获取构造器参数列表
            Class[] constructorParameterArray = constructorPart.getParameterTypes();
            // 打印构造器参数列表
            System.out.print(constructorModifier + " " + constructorName + "(");
            for (Class constructorParameterPart : constructorParameterArray) {
                System.out.print(constructorParameterPart.getName() + " ");
            }
            System.out.println(")");
        }
        System.out.println();
    }
}

运行截图

3. 利用Constructor类实例化对象

一般而言,我们关心的不只是获取到对象构造器的具体信息,更重要的是如何利用反射实例化对象,针对对象实例化,Constructor提供了两种类型的方法:

  1. getConstructor(Class<?>... parameterTypes):获取指定形参表的构造方法,可借助其获取无参/指定参数的构造方法;
  2. newInstance(Object ... initargs):通过形参表传递实例化对象参数,与getConstructor配合使用;

注意:Class也存在newInstance()方法,但仅能用来调用类的无参构造器

4. Constructor实例化对象测试实例

package cn.byuan.example;
import cn.byuan.entity.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 构造器调用实例
 *
 * @author byuan
 * @date 2022-01-26
 */
public class ConstructorsInvokeExample {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class studentClass = Student.class;
        // Class 类的 newInstance 方法
        studentClass.newInstance();
        // 1. 调用公有无参构造器
        Object object1 = studentClass
                .getConstructor()
                .newInstance();
        System.out.println(object1.getClass());
        // 2. 调用公有满参构造器
        Constructor studentConstructorFull = studentClass
                .getConstructor(String.class, String.class, String.class, Integer.class);
        Object object2 = studentConstructorFull
                .newInstance("2022001", "赵一", "男", 18);
        System.out.println(object2);
        // 3. 调用私有构造器
        Constructor studentConstructorPrivate = studentClass
                .getDeclaredConstructor(String.class, Integer.class);
        // 私有构造器需将 accessible 设置为 true, 取消语言访问检查
        studentConstructorPrivate.setAccessible(true);
        Object object3 = studentConstructorPrivate
                .newInstance("女", 19);
        System.out.println(object3);
    }
}

运行截图

(四)反射中的重要类之Method

Method类描述了类的方法信息

1. Method类的获取与常用方法

Class类为我们提供了两个方法用以获取Method类:

  1. getDeclaredMethods():获取所有非构造方法
  2. getMethods():仅可获取公有非构造方法

对于任意方法都可分为修饰符,方法名,形参表,方法体四部分;Method为其组成部分提供了对应方法:

  1. getModifiers():获取方法修饰符相加值,想要获取明确标识需要通过Modifier常量的toString方法进行解码
  2. getName():获取方法名称
  3. getParameterTypes():获取方法形参表

2. Method类测试实例

package cn.byuan.example;
import cn.byuan.entity.Student;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 获取非构造方法的几种方式
 *
 * @author byuan
 * @date 2022-01-26
 */
public class GetMethodExample {
    public static void main(String[] args) {
        Class studentClass = Student.class;
        // 获取非构造方法的两个方法: getDeclaredMethods, getMethods
        // 1. getDeclaredMethods: 获取所有非构造方法
        Method[] declaredMethodArray = studentClass.getDeclaredMethods();
        printMethodInformation(declaredMethodArray);
        // 2. getMethods, 仅可获取公有非构造方法
        Method[] methodArray = studentClass.getMethods();
        printMethodInformation(methodArray);
    }

    /**
     * 打印非构造器方法信息
     *
     * @param methodArray 构造器对象列表
     * */
    public static void printMethodInformation(Method[] methodArray) {
        for (Method methodPart : methodArray) {
            System.out.println("直接打印非构造方法对象: " + methodArray);
            // 获取非构造器方法修饰符
            String methodModifier = Modifier.toString(methodPart.getModifiers());
            // 获取非构造器方法名称
            String methodName = methodPart.getName();
            String methodReturnType = methodPart.getReturnType().getName();
            // 获取非构造方法参数列表
            Class[] constructorParameterArray = methodPart.getParameterTypes();
            // 打印非构造方法参数列表
            System.out.print(methodModifier + " " + methodReturnType + " " + methodName + "(");
            for (Class methodParameterPart : constructorParameterArray) {
                System.out.print(methodParameterPart.getName() + " ");
            }
            System.out.println(")");
        }
        System.out.println();
    }
}

运行截图

3. 利用Method调用非构造方法

与利用Constructor实例化对象相似,Method同样需要两个方法用以调用非构造方法

  1. getDeclaredMethod(方法名, 形参表数组): 获取所有构造方法
  2. invoke(对象实例, 参数数组):方法调用

4. Method调用非构造方法测试实例

package cn.byuan.example;
import cn.byuan.entity.Student;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 非构造器方法调用实例
 *
 * @author byuan
 * @date 2022-01-26
 */
public class MethodInvokeExample {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        Class studentClass = Student.class;
        // 对于私有的非构造方法, 需要使用 getDeclaredMethod 进行获取
        // getDeclaredMethod(方法名, 形参表数组)
        Method studentSpeakMethod = studentClass.getDeclaredMethod("speak", new Class[]{String.class});
        // 取消语言访问检查
        studentSpeakMethod.setAccessible(true);
        // invoke(对象实例, 参数数组)
        Object object = studentSpeakMethod.invoke(studentClass.newInstance(), "Hello, world");
        System.out.println(object);
    }
}

运行截图

四、综合实战:利用反射机制编写对象拷贝工具类

在实际项目中,我们经常会遇到POJO与VO等类型对象进行相互转换的情况,如果直接进行转换则会使用大量的样板代码,为消除这样的代码,我们可以写一个简单的对象拷贝工具类进行解决;

(一)业务分析

通过反射获取源对象Field数组,并利用Field类提供的set/get方法实现同名属性的拷贝;

(二)实体类准备

创建Student类

package cn.byuan.entity;

/**
 * 学生实体类
 *
 * @author byuan
 * @date 2022-01-25
 */
public class Student {

    /**
     * 学生学号, 公共变量, 默认值: defaultStudentNo
     * */
    public String studentNo = "defaultStudentNo";

    /**
     * 学生姓名, 公共变量, 默认值: defaultStudentName
     * */
    public String studentName = "defaultStudentName";

    /**
     * 学生性别, 私有变量, 默认值: defaultStudentSex
     * */
    private String studentSex = "defaultStudentSex";

    /**
     * 学生年龄, 私有变量, 默认值: 0
     * */
    private Integer studentAge = 0;

    /**
     * 公有无参构造方法
     * */
    public Student() {

    }

    /**
     * 公有满参构造方法
     * */
    public Student(String studentNo, String studentName, String studentSex, Integer studentAge) {
        this.studentNo = studentNo;
        this.studentName = studentName;
        this.studentSex = studentSex;
        this.studentAge = studentAge;
    }

    /**
     * 私有构造方法
     * */
    private Student(String studentSex, Integer studentAge) {
        this.studentSex = studentSex;
        this.studentAge = studentAge;
    }

    public String getStudentNo() {
        return studentNo;
    }

    public Student setStudentNo(String studentNo) {
        this.studentNo = studentNo;
        return this;
    }

    public String getStudentName() {
        return studentName;
    }

    public Student setStudentName(String studentName) {
        this.studentName = studentName;
        return this;
    }

    public String getStudentSex() {
        return studentSex;
    }

    public Student setStudentSex(String studentSex) {
        this.studentSex = studentSex;
        return this;
    }

    public Integer getStudentAge() {
        return studentAge;
    }

    public Student setStudentAge(Integer studentAge) {
        this.studentAge = studentAge;
        return this;
    }

    @Override
    public String toString() {
        return "Student{" +
                "studentNo = " + this.studentNo + ", " +
                "studentName = " + this.studentName + ", " +
                "studentSex = " + this.studentSex + ", " +
                "studentAge = " + this.studentAge +"}";
    }

    /**
     * 学生类说话方法
     * */
    private String speak(String message) {
        return this.studentName + " : " + message;
    }
}

创建StudentOut类

package cn.byuan.api.out;

import cn.byuan.entity.Student;

/**
 * 学生类出参
 *
 * @author byuan
 * @date 2022-01-26
 */
public class StudentOut {
    /**
     * 学生学号, 公共变量
     * */
    private String studentNo;

    /**
     * 学生姓名, 公共变量
     * */
    private String studentName;

    /**
     * 学生性别, 私有变量
     * */
    private String studentSex;

    /**
     * 学生年龄, 私有变量
     * */
    private Integer studentAge;

    public String getStudentNo() {
        return studentNo;
    }

    public StudentOut setStudentNo(String studentNo) {
        this.studentNo = studentNo;
        return this;
    }

    public String getStudentName() {
        return studentName;
    }

    public StudentOut setStudentName(String studentName) {
        this.studentName = studentName;
        return this;
    }

    public String getStudentSex() {
        return studentSex;
    }

    public StudentOut setStudentSex(String studentSex) {
        this.studentSex = studentSex;
        return this;
    }

    public Integer getStudentAge() {
        return studentAge;
    }

    public StudentOut setStudentAge(Integer studentAge) {
        this.studentAge = studentAge;
        return this;
    }

    @Override
    public String toString() {
        return "StudentOut{" +
                "studentNo = " + this.studentNo + ", " +
                "studentName = " + this.studentName + ", " +
                "studentSex = " + this.studentSex + ", " +
                "studentAge = " + this.studentAge +"}";
    }
}

(三)工具类编写

package cn.byuan.util;
import cn.byuan.api.out.StudentOut;
import cn.byuan.entity.Student;
import java.lang.reflect.Field;

/**
 * 对象属性拷贝工具类
 *
 * @author byuan
 * @date 2022-01-26
 */
public class BeanUtil {
    /**
     * 对象拷贝工具
     *
     * @param sourceObject 源对象
     * @param destClass 目的对象对应 Class
     *
     * @return 拷贝完毕后对象
     * */
    public static <T> T copyObject(Object sourceObject, Class<T> destClass) {
        if (sourceObject == null) {
            return null;
        }

        try {

            T destObject = destClass.newInstance();

            copyField(sourceObject, destObject);

            return destObject;

        } catch (InstantiationException e) {
            e.printStackTrace();

        } catch (IllegalAccessException e) {
            e.printStackTrace();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 对象属性拷贝工具
     *
     * @param sourceObject 源对象
     * @param destObject 目的对象
     * */
    private static void copyField(Object sourceObject, Object destObject) {
        if (sourceObject == null || destObject == null) {
            return;
        }

        // 获取源对象所有字段
        Field[] sourceFieldArray = sourceObject.getClass().getDeclaredFields();
        for (Field sourceFieldPart : sourceFieldArray) {
            // 取消语言访问检查
            sourceFieldPart.setAccessible(true);
            String sourceFieldName = sourceFieldPart.getName();
            try {
                // 根据属性名称获取目标对象对应类字段
                Field destField = destObject
                        .getClass()
                        .getDeclaredField(sourceFieldName);
                destField.setAccessible(true);
                destField.set(destObject, sourceFieldPart.get(sourceObject));
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        Student student = new Student("2022001", "赵一", "男", 18);
        StudentOut studentOut = copyObject(student, StudentOut.class);
        System.out.println(studentOut);
    }
}

运行截图

总结

到此这篇关于Java高级语法学习之反射的文章就介绍到这了,更多相关Java高级语法反射内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JAVA反射机制实例教程

    本文以实例形式详细讲述了Java的反射机制,是Java程序设计中重要的技巧.分享给大家供大家参考.具体分析如下: 首先,Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性.例如,使用它能获得 Java 类中各成员的名称并显示出来. Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性.例如,Pascal.C 或者 C++ 中就没有办法在程序中获得函数

  • java反射应用详细介绍

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 复制代码 代码如下: package Reflect; /** * 通过一个对象获得完整的包名和类名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args)

  • Java反射机制的实现详解

    很多主流框架都使用了反射技术.像ssh框架都采用两种技术 xml做配置文件+反射技术. 与反射有关的类包. java.lang.reflect.*;和java.lang.Class; Java中所有类型(包括基本类型)都对应一个Class对象,这个Class就是java.lang.Class.即每一个类型,在Class中都有一个Class对象跟它对应.Class 没有公共构造方法.注意不是没有,是没有公共的. 如何获得Class对象 复制代码 代码如下: .针对每一个对象.getCalss(),

  • Java反射机制的学习总结

    一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码, Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成驱动对象实例,并不知道它的具体含义.听了反射机制这节课后,才知道,原来这

  • java反射获取和调用方法

    Class类中获取方法: public Method[] getMethods();//获取包括自身和继承(实现)过来的所有的public方法--Method不支持泛型<>,即后面不接<> public Method[] getDeclaredMethods();//获取自身所有的方法(private.public.protected,和访问权限无关),不包括继承的 在jdk1.8后可以直接获取私有属性的方法不需要设置权限 但是仅限于getDeclaredMethod方法 对于Me

  • java反射机制示例详解

    1.什么是反射?一个类有多个组成部分,例如:成员变量,方法,构造方法等.反射就是加载类,并解剖出类的各个组成部分. 2.加载类java中有一个Class类用于代表某一个类的字节码.Class类既然代表某个类的字节码,那就要提供加载某个类字节码的方法:forName().   此方法用于加载某个类的字节码到内存中,并使用class对象进行封装.另外2种得到class对象的方式:类名.class对象.getClass() 先创建一个简单的Person类 复制代码 代码如下: public class

  • Java反射机制详解

    本文较为详细的分析了Java反射机制.分享给大家供大家参考,具体如下: 一.预先需要掌握的知识(java虚拟机) java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 1.这个类型的全

  • Java高级语法学习之反射详解

    目录 一.什么是反射 二.准备测试:实体类的创建 三.反射中的几个重要类及方法 (一)反射中的重要类之Class (二)反射中的重要类之Field (三)反射中的重要类之Constructor (四)反射中的重要类之Method 四.综合实战:利用反射机制编写对象拷贝工具类 (一)业务分析 (二)实体类准备 (三)工具类编写 总结 一.什么是反射 java.lang包提供java语言程序设计的基础类,在lang包下存在一个子包:reflect,与反射相关的APIs均在此处: 官方对reflect

  • Java基本语法之内部类示例详解

    目录 1.内部类概念及分类 2.实例内部类 2.1实例内部类的创建 2.2使用.this和.new 2.3内部类实现迭代打印 2.4内部类的继承 3.静态内部类 4.匿名内部类 1.内部类概念及分类 将一个类定义在另一个类的内部或者接口内部或者方法体内部,这个类就被称为内部类,我们不妨将内部类所在的类称为外围类,除了定义在类,接口,方法中的内部类,还有一种特殊的内部类,那就是使用关键字new创建一个匿名类的对象,而这个匿名类其实就是一个内部类,具体说是一个匿名内部类,经常用于传入构造器实参构造对

  • Java事务管理学习之Hibernate详解

    环境与版本 hibernate 版本:Hibernate 4.2.2 (下载后的文件名为hibernate-release-4.2.2.Final.zip,解压目录hibernate-release-4.2.2.Final) 数据库: Oracle 10g 导入lib\required 中的所有jar 包 理论说明 1.SessionFactory负责创建Session,SessionFactory是线程安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取Session实

  • Java事务管理学习之JDBC详解

    什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isolation)和持久性(durability)的缩写.事务的原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效.一致性表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态.隔离性表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见.持久性表示已提交的数据在事务

  • Java基础之反射详解

    前言 反射是我们框架的灵魂,反射也是我们框架的一个底层基石,没有反射也就没有框架,如果我们学好了反射,对我们阅读框架底层是有很大班助的--阿俊.有些文章上来就讲反射,就会很懵逼,不知道是干啥的,所以我们就引出一些问题来看看为什么需要反射 一.一个需求引出反射 看下面的问题 根据配置文件reflection.properties指定信息,创建People对象并调用方法hi classullpath= com.reflection.People method=hi 思考:使用现有技术,能做吗? 我们

  • Java Spring5学习之JdbcTemplate详解

    一.JdbcTemplate Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作 二.实战 2.1 引入依赖 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.24</version> </dependency> <!-

  • Java基础学习之构造方法详解

    目录 一.构造方法概述 二.构造方法的注意事项 三.标准类制作 一.构造方法概述 构造方法是一种特殊的方法 作用:创建对象Student stu = new Student(); 格式: pucli class 类名{        修饰符 类名(参数){        } } 功能:主要是完成对象数据的初始化 示例代码: class Student { private String name; private int age; //构造方法 public Student() { System.

  • Java基础学习之接口详解

    目录 概述 定义格式 含有抽象方法 含有默认方法和静态方法 含有私有方法和私有静态方法 基本的实现 实现的概述 抽象方法的使用 默认方法的使用 静态方法的使用 私有方法的使用 接口的多实现 抽象方法 默认方法 静态方法 优先级的问题 接口的多继承 其他成员特点 概述 接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量.构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9). 接

  • Java的类型擦除式泛型详解

    Java选择的泛型类型叫做类型擦除式泛型.什么是类型擦除式泛型呢?就是Java语言中的泛型只存在于程序源码之中,在编译后的字节码文件里,则全部泛型都会被替换为原来的原始类型(Raw Type),并且会在相应的地方插入强制转型的代码. 因此,对于运行期间的Java程序来说ArrayList< Integer>和ArrayList< String>其实是同一个类型.这也就是Java选择的泛型类型叫做类型擦除式泛型的原因. ArrayList<String> stringAr

  • java操作mongoDB查询的实例详解

    java操作mongo查询的实例详解 前言: MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型.Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且

随机推荐