一.Java反射的概念:

在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。 对于任意一个对象,可以调用它的任意一个方法。 这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。

反射结构分析

Java反射原理:将普通java类的各个组成部分分别封装为对象,包括类的成员变量、成员方法、成员构造。

其所对应的对象分别是:Field、Method、Constructor。

2.反射的相关函数,用法

一.class对象

通过类的字节码对象,即Class对象获取

Class类将所有的普通java类作为对象。

三个阶段获取Class对象的方法

Class.forName(“全类名”)

将字节码文件加载进内存,并返回class对象。多用于配置文件

类名.class

通过类名的class属性获取,该方法常用于参数的传递。

对象名.getClass()

getClass()方法定义于Object类中,用于对象获取字节码。

同一个字节码文件(*.class)在程序运行过程中,只会被加载一次。无论通过哪种方法获取的class对象都是同一个。

Class对象中的常用方法

获取成员变量

方法名

作用

Field[] getFields()

获取所有public修饰的成员变量

Field getField(String name)

获取指定名称的 public修饰的成员变量

Field[] getDeclaredFields()

获取所有的成员变量,不考虑修饰符

Field getDeclaredField(String name)

获取指定名称的成员变量,不考虑修饰符

Field类的常用方法

方法名

作用

void set(Object obj, Object value)

设置值,将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

Object get(Object obj)

获取值,返回指定对象上此 Field 表示的字段的值

setAccessible(true)

忽略访问权限修饰符的安全检查

当访问私有变量时,必须设置setAccessible(true)来忽略访问权限修饰符的安全检查,否则没有权限访问。

案例

public static void main(String[] args) throws Exception{

Student student=new Student(); //新建一个对象

student.setId("01"); //设置改对象的id值

student.setName("tom"); //设置改对象的name值

student.setBirthday("2020-03-05"); //设置改对象的Birthday值

student.setSex("男"); //设置改对象的性别值

Class> clazz =Class.forName("Student"); //获取该类

Class> clazz2=Student.class; //类.class

Class> clazz3=student.getClass(); //对象.getclass

Field field = null;

field = clazz.getDeclaredField("id");//获取类的指定属性包含私有属性

int modifiers =field.getModifiers(); //获取类的指定属性的修饰符

if(Modifier.isPrivate(modifiers)){ //指定属性的修饰符是否为private

field.setAccessible(true); //如果属性为private就设置为可以访问

}

Object id =field.get(student); //获取该对象的属性值

if(id instanceof String){

System.out.println("id = " + id);

field.set(student,"002"); //更改该对象的属性值

System.out.println("id = " + student.getId());

}

}

student类

public class Student {

private String id;

private String name;

private String sex;

private String birthday;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public String getBirthday() {

return birthday;

}

public void setBirthday(String birthday) {

this.birthday = birthday;

}

}

获取构造函数的相关方法

获取构造方法

方法名

作用

Constructor>[] getConstructors()

返回此 Class 对象所表示的类的所有公共构造方法。

ConstructorgetConstructor(类>... parameterTypes)

返回此 Class 对象所表示的类的指定参数公共构造方法。

Constructor>[] getDeclaredConstructors()

返回此 Class 对象所表示的类的所有构造方法,不考虑修饰符。

ConstructorgetDeclaredConstructor(类>... parameterTypes)

返回此 Class 对象所表示的类的指定参数构造方法,不考虑修饰符。

Constructor类中的常用方法

方法名

作用

T newInstance(Object... initargs)

实例化一个对象

Class cls = Student.class;

//方法一

Constructor c1 = cls.getConstructor(String.class,String.class,String.class,String.class);

Object s1 = c1.newInstance("帝释天","24","看小说","001");

System.out.println(s1);

//方法二 调用空参构造

Constructor c2 = cls.getConstructor();

Object s2 = c2.newInstance();

System.out.println(s2);

//方法三 由Class对象直接创建

Object c3 = cls.newInstance();

System.out.println(c3);

获取函数的相关方法

获取成员方法

方法名

作用

Method[] getMethods()

获取所有public修饰的成员方法

Method getMethod(String name, 类>... parameterTypes)

获取指定参数形式的 public修饰的成员方法

Method[] getDeclaredMethods()

获取所有成员方法,不考虑修饰符

Method getDeclaredMethod(String name, 类>... parameterTypes)

获取指定参数形式的成员方法,不考虑修饰符

Method类中的常用方法

方法名

作用

Object invoke(Object obj, Object... args)

执行方法,对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

String getName

获取方法名

Class cls = Student.class;

Student stu = new Student();

//执行带参数方法

Method song1 = cls.getMethod("song", String.class);

song1.invoke(stu, "你确定这就是爱吗");

//执行无参数方法

Method song2 = cls.getMethod("song");

song2.invoke(stu);

//获取方法名

Method[] methods = cls.getMethods();

for (Method method : methods) {

System.out.println(method);

}

public void song() {

System.out.println("We are the word...");

}

public void song(String songs) {

System.out.println("我会唱"+songs);

}

invoke(Object obj, Object... args) 对该对象,执行该方法;

3.比较的相关工具类的书写

package com.etoppaas.insureagent.common.utils;

import com.etoppaas.common.tools.EmptyUtils;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

/**

* 比较相同类的相同属性值是否相同

*/

public class CompareClassUtil {

public static Boolean compareTwoClass(Object class1, Object class2, ListignoreFieldList) throws ClassNotFoundException, IllegalAccessException {

//动态的获取指定对象的class

Class> clazz1 = class1.getClass();

Class> clazz2 = class2.getClass();

// 获取类中所有的属性(public、protected、default、private),但不包括继承的属性,返回 Field 对象的一个数组

Field[] field1 = clazz1.getDeclaredFields();

Field[] field2 = clazz2.getDeclaredFields();

//遍历属性列表field1

for (int i = 0; i < field1.length; i++) {

//遍历属性列表field2

for (int j = 0; j < field2.length; j++) {

//如果field1[i]属性名与field2[j]属性名内容相同

if (field1[i].getName().equals(field2[j].getName())) {

Boolean checkIgnoreField = true;

if (EmptyUtils.isNotEmpty(ignoreFieldList)) {

for (int ignoreFieldNum = 0; ignoreFieldNum < ignoreFieldList.size(); ignoreFieldNum++) {

//如果要忽略的类型里存在,就跳过这个方法

if (field1[i].getName().equals(ignoreFieldList.get(ignoreFieldNum))) {

checkIgnoreField = false;

}

}

if (checkIgnoreField) {

//调过本次循环的下面语句执行

continue;

}

if (!compareTwo(field1[i], field2[j], class1, class2)) {

return false;

}

break;

} else {

if (!compareTwo(field1[i], field2[j], class1, class2)) {

return false;

}

break;

}

}

}

}

return true;

}

/**

* 对比两个数据是否内容相同

*

* @param

* @return boolean类型

*/

public static boolean compareTwo(Field field1, Field field2, Object class1, Object class2) throws IllegalAccessException {

//让我们可以访问私有变量的值

field1.setAccessible(true);

field2.setAccessible(true);

//如果field1[i]属性值与field2[j]属性值内容不相同

//为了不重写equals方法目前只能比较基础的类型

if ("java".equals(field1.getGenericType().toString())) {

}

//返回该类下面对应的该属性值,并返回结果

Object object1 = field1.get(class1);

Object object2 = field2.get(class2);

if (object1 == null && object2 == null) {

return true;

}

if (object1 == null && object2 != null) {

return false;

}

if (object1.equals(object2)) {

return true;

}

return false;

}

}

java比较两个类的值不相同_java 反射---------比较两个相同类型的对象相同属性的属性值是否相同的具体调用...相关推荐

  1. java定义一个长方形类,该类中具有长方形长宽两种属性,并具有相应的构造方法属性访问方法,计算长方形的周长和面积的方法,要求输出长是5,宽是4的长方形

    定义一个长方形类,该类中具有长方形长宽两种属性,并具有相应的构造方法 属性访问方法,计算长方形的周长和面积的方法,要求输出长是5,宽是4的长方形 public class test3 {public ...

  2. java实例成员和类成员变量的区别_Java之实例成员与类成员

    一:实例变量和类变量 类体中的成员变量可细分为实例变量和类变量.用关键字static修饰的称作类变量,否则称为实例变量.例如: class Dog{ float x;    //实例变量 static ...

  3. java 实例变量是类的成员变量吗_JAVA中成员变量,局部变量,实例变量,类变量,有什么关系,,?...

    展开全部 java易混淆概念之类变量32313133353236313431303231363533e4b893e5b19e31333365643662.实例变量.局部变量 类变量.实例变量.局部变量 ...

  4. java 嵌套类 map_java – 将groupingBy用于嵌套Map,但收集到不同类型的对象

    所以我有这个"工作"的代码(为简单起见替换一些名称): Map>> someMap = someListOfClassA.stream() .filter(...) . ...

  5. java截取某两个字符之间的字串_Java截取特定两个标记之间的字符串实例

    Java截取特定两个标记之间的字符串实例 如有一串字符串: higklmnopq java代码如下: public class StringTest { public static void main ...

  6. java 里面怎么截取倒数第几个字_Java反射是什么

    前言 Java的反射特性是一项非常强大和有用的功能,它使得我们可以轻松的在运行时观察到类实例的内部状态,并且可以动态的操作实例,从而为Java语言提供更多更灵活的想象空间.随便举几个例子:使用反射可以 ...

  7. Java读书笔记05 类与对象

    本文为java中对象与类等的基本知识,包括方法.构造.析构.静态域.初始化.包.路径等. 对象与对象变量 在Java中,任何对象变量的值都是对存储在另外一处的一个对象的引用.new操作符的返回值也是一 ...

  8. java反射随意值_Java反射笔记

    Java反射 反射库提供了一个丰富且精巧的工具集,可以用来编写能够动态操纵Java代码的程序.能够分析类能力的程序称为反射(reflective).反射机制的功能极为强大,反射机制可以用来: 在运行时 ...

  9. method java_解析Java中的Field类和Method类

    Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够找出有关字段声明的全部信息,并且能够操纵某个特 ...

  10. java method field_java_解析Java中的Field类和Method类,Field类 Field类中定义了一些方 - phpStudy...

    解析Java中的Field类和Method类 Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够 ...

最新文章

  1. EBS 抓trace 文件
  2. “模板类与友元”那些事(C++)
  3. php进程学习(一)
  4. Cortex-M3-MPU(存储器保护单元)
  5. 原码一位乘法器设计_数字IC校招基础知识点复习(七)——超前进位加法器、Wallace树、Booth乘法器...
  6. 7-166 二分法求多项式单根 (20 分)
  7. win10 update 关闭计算机,Win10关闭Windows Update服务的方法
  8. Redis单机版半自动安装
  9. java tomcat 日志分析工具_设计一个Tomcat访问日志分析工具
  10. 作为PHP开发者请务必了解Composer
  11. 2022百度之星第一场初赛
  12. python中math isnan_带有Python示例的math.isnan()方法
  13. BOS启动的客户端,打开序时簿只显示一行
  14. 普通住宅和商住公寓购房扫盲
  15. setcpu_SetCPU中文版
  16. PHY--PUSCH
  17. binlog流程 mysql_MySQL binlog分析程序:Open Replicator
  18. MOSFET类型识别小结
  19. #Paper Reading#Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts
  20. SQL入门之第十六讲——总结下之前的SQL语句书写顺序

热门文章

  1. tortoiseHg查看后一个版本和parent版本的不同
  2. 我是如何一步步解决问题 让Spring MVC返回HTML类型的视图
  3. 工欲善其事必先利其器——MySQL数据库(2),查询操作
  4. DDoSCoin:加密货币奖励用户参与 DDoS 攻击
  5. docker-compose简单使用
  6. 数据结构期末复习第一章绪论
  7. 转:SQL注入攻击的原理
  8. Linux音频驱动-AOSC之Platform
  9. KVM 介绍(5):libvirt 介绍 [ Libvrit for KVM/QEMU ]
  10. SEGGER-RTT调试(代替串口printf输出)的使用方法