精华内容
下载资源
问答
  • java new和反射对比

    2021-08-10 19:01:14
    还是不太清晰反射和new在执行过程中的本质区别。 说上new和反射的区别。都可罗列一堆。 new是静态编译,在类进行编译的时候吧所有模块都编译到exe了。当启动这个exe的时候所有模块都加载进入内存。 反射是动态编译。...

    很难过。逛了一圈。还是不太清晰反射和new在执行过程中的本质区别。

    说上new和反射的区别。都可罗列一堆。
    new是静态编译,在类进行编译的时候吧所有模块都编译到exe了。当启动这个exe的时候所有模块都加载进入内存。
    反射是动态编译。编译时没有把模块编译到一起,启动程序的时候也不会加载,而是在运行时用到那个模块就调用哪个模块。

    所以RTTI和反射之间真正的区别只在于,对RTTI来说,编译器在编译时打开和检查.class文件。(换句话说,我们可以用“普通”方式调用对象的所有方法。)而对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。
    ----《java编程思想》

    其实我感觉,反射是很好理解的。

    jvm类加载中,加载阶段的功能就是将字节码从不同的数据源转化为二进制字节流加载到内存,并生成一个代表着各类的java.lang.Class对象。这个Class对象对任意类都是唯一的,他存储了其类的所有信息。

    类是程序的一部分,每次编写并且编译了一个新类,都会生成一个Class对象(更恰当地说,是被保存在一个同名的.class文件中)。 --------《java编程思想》

    反射就相当于是直接获取这个对象。所以他能使用类的所有所有。
    是的。我理解的反射就是这么简单。深入到了jvm层面,思路清晰,并且应该也没有错。。。

    那new呢?
    所有关于new一个对象的过程,都是一通火花带闪电。
    在这里插入图片描述
    在这里插入图片描述

    我觉得非常的难受。说好的静态编译呢,说好的编译时打开calss文件呢?
    然后我发现我好像进入了一个误区。
    我一直在思考的是,一个类,new加载和反射加载有什么不一样
    答案很明显:没什么不一样。
    所以new和反射没什么不一样,这个话题就此结束。。。

    nonono。
    类的加载没什么不一样,最后都会生成一个Class对象
    来一张《深入理解java虚拟机》的图
    在这里插入图片描述
    在这里插入图片描述
    1和2明确说明new和反射都会触发类“初始化”(反射中的.class好像不会初始化。。。)而初始化,肯定都会生成唯一的Class对象啊

    所以就jvm的类加载层面而言。new和反射没区别

    下面纯纯属于个人推测,保写不保对。。。

    区别在之后。就如同

    public class SS{
    String s = new String();
    }

    先说String s=new String()。
    不管之前有没有加载,反正现在堆内存里肯定有一个String的Class对象,其保存了String的所有信息。
    而下一步,才是new的表现:创建对象
    在这里插入图片描述
    开始串起来了。

    如果不知道某个对象的确切类型,RTTI可以告诉你。但是有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别他,并利用这些信息做一些有用的事。话句话说,在编译时,编译器必须知道所有要通过RTTI来处理的类 -------《java编程思想》

    new String()这一句话,就是让你知道刚刚加载的String的Class对象类型为String。之后不是还要创建对象么。在知道对象类型后,就可以创建String的对象,并且把引用,给到class SS。这就是一开始说的,静态编译把所有模块都编译到了一起。SS这个类中直接包含了String这个new出来的类。他们的耦合性极其之高。

    至于反射。懂的都懂
    是的,戛然而止。哈哈哈

    图中截图除了我自己拍的,还有来自这两篇文章
    https://www.cnblogs.com/JackPn/p/9386182.html
    https://blog.csdn.net/qq_32379477/article/details/90239891

    展开全文
  • Java各种反射性能对比

    2021-02-26 13:42:33
    对各种方法实现get方法的性能进行了一个测试...通过Java Class类自带的反射获得Method测试4.使用Java自带的Property类获取Method测试5.BeanUtils的getProperty测试1 测试用Bean类测试定义了如下一个bean类。 public...

    对各种方法实现get方法的性能进行了一个测试。

    总共有5个测试,,每个测试都是执行1亿次

    1. 直接通过Java的get方法

    2.通过高性能的ReflectAsm库进行测试

    3.通过Java Class类自带的反射获得Method测试

    4.使用Java自带的Property类获取Method测试

    5.BeanUtils的getProperty测试

    1 测试用Bean类

    测试定义了如下一个bean类。

    6de016d966602bfe03745ad2e599328d.gif

    public class SimpleBean {

    private String name;

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    }

    f9360a9b74da0316134ef56011443697.gif

    注意定义要严格遵守JavaBean规范,否则在使用和反射相关工具时会出现NoSuchMethodException异常,或者导致性能非常差,JavaBean规范中最重要的几点如下:

    1.类必须是public, 拥有public无参构造器,这样能够通过反射newInstance()动态构建对象.

    String className = ...;

    Class beanClass = Class.forName(className);

    Object beanInstance = beanClass.newInstance();

    2.因为反射newInstance使用的是无参构造器, 所以对象实例化和配置是分开的

    3.每一个property都有一个public的getter和setter方法, 命名方式是get/set+首字母大写的property名

    经测试在SimpleBean为public时,1亿次调用method.invoke方法:

    javaReflectGet 100000000 times using 218 ms

    而SimpleBean为默认包可见时,1一亿次调用method.invoke方法:

    javaReflectGet 100000000 times using 12955 ms

    2.测试代码

    d818f4092e4b4a21bba7eb983fd1d27d.gif

    public class TestIterator {

    private long times = 100_000_000L;

    private SimpleBean bean;

    private String formatter = "%s %d times using %d ms";

    @Before

    public void setUp() throws Exception {

    bean = new SimpleBean();

    bean.setName("haoyifen");

    }

    //直接通过Java的get方法

    @Test

    public void directGet() {

    Stopwatch watch = Stopwatch.createStarted();

    for (long i = 0; i < times; i++) {

    bean.getName();

    }

    watch.stop();

    String result = String.format(formatter, "directGet", times, watch.elapsed(TimeUnit.MILLISECONDS));

    System.out.println(result);

    }

    //通过高性能的ReflectAsm库进行测试,仅进行一次methodAccess获取

    @Test

    public void reflectAsmGet() {

    MethodAccess methodAccess = MethodAccess.get(SimpleBean.class);

    Stopwatch watch = Stopwatch.createStarted();

    for (long i = 0; i < times; i++) {

    methodAccess.invoke(bean, "getName");

    }

    watch.stop();

    String result = String.format(formatter, "reflectAsmGet", times, watch.elapsed(TimeUnit.MILLISECONDS));

    System.out.println(result);

    }

    //通过Java Class类自带的反射获得Method测试,仅进行一次method获取

    @Test

    public void javaReflectGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {

    Method getName = SimpleBean.class.getMethod("getName");

    Stopwatch watch = Stopwatch.createStarted();

    for (long i = 0; i < times; i++) {

    getName.invoke(bean);

    }

    watch.stop();

    String result = String.format(formatter, "javaReflectGet", times, watch.elapsed(TimeUnit.MILLISECONDS));

    System.out.println(result);

    }

    //使用Java自带的Property属性获取Method测试,仅进行一次method获取

    @Test

    public void propertyGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, IntrospectionException {

    Method method = null;

    BeanInfo beanInfo = Introspector.getBeanInfo(SimpleBean.class);

    PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

    if (propertyDescriptor.getName().equals("name")) {

    method = propertyDescriptor.getReadMethod();

    break;

    }

    }

    Stopwatch watch = Stopwatch.createStarted();

    for (long i = 0; i < times; i++) {

    method.invoke(bean);

    }

    watch.stop();

    String result = String.format(formatter, "propertyGet", times, watch.elapsed(TimeUnit.MILLISECONDS));

    System.out.println(result);

    }

    //BeanUtils的getProperty测试

    @Test

    public void beanUtilsGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {

    Stopwatch watch = Stopwatch.createStarted();

    for (long i = 0; i < times; i++) {

    BeanUtils.getProperty(bean, "name");

    }

    watch.stop();

    String result = String.format(formatter, "beanUtilsGet", times, watch.elapsed(TimeUnit.MILLISECONDS));

    System.out.println(result);

    }

    }

    a74b0445f9f51745bcf33c8e0fbd2f54.gif

    3.测试结果

    在4核i5-4590@3.30GHz机器上跑以上测试,经过多次测量,基本在以下数值范围附近,测试数据如下:

    1. directGet 100000000 times using 37 ms

    2. reflectAsmGet 100000000 times using 39 ms

    3. javaReflectGet 100000000 times using 222 ms

    4. propertyGet 100000000 times using 335 ms

    5. beanUtilsGet 100000000 times using 20066 ms

    4.结果分析

    1.使用reflectAsm库的性能能和直接调用get方法持平

    2.Java自带的反射性能大致为直接get的1/6和1/9.

    3.BeanUtils的getProperty非常的慢,为直接get性能的1/500,为Java自带反射性能的1/100和1/60.

    转载至:https://www.cnblogs.com/Frank-Hao/p/5839096.html

    展开全文
  • 1、对比两个对象的属性差异/*** 获取两个对象之间的变化(仅对比当前对象写的属性,不会对比父类写的属性)* @param oldBean* @param newBean* @return*/public String getObjectDifferent(Object oldBean, Object new...

    1、对比两个对象的属性差异

    /**

    * 获取两个对象之间的变化(仅对比当前对象写的属性,不会对比父类写的属性)

    * @param oldBean

    * @param newBean

    * @return

    */

    public String getObjectDifferent(Object oldBean, Object newBean) {

    if (oldBean != null && newBean!= null) {

    String modifyValue = "";

    try {

    Class clazz = oldBean.getClass();

    List fields = new ArrayList<>();

    fields.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));

    //如果父类属性变化也记录

    fields.addAll(new ArrayList<>(Arrays.asList(clazz.getSuperclass().getDeclaredFields())));

    for (Field field : fields) {

    if ("serialVersionUID".equals(field.getName())) {

    continue;

    }

    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), oldBean.getClass());

    Method getMethod = pd.getReadMethod();

    Object o1 = getMethod.invoke(oldBean);

    Object o2 = getMethod.invoke(newBean);

    if (o1 == null || o2 == null) {

    continue;

    }

    if (!o1.toString().equals(o2.toString())) {

    modifyValue += field.getName() + ":" + o1 + "->" + o2 + "; ";

    }

    }

    return modifyValue;

    } catch (Exception e) {

    e.printStackTrace();

    return e.toString();

    }

    } else {

    log.info("传入对象为空,保存 “修改操作” 系统敏感操作记录失败");

    return "保存 “修改操作” 传入对象为空";

    }

    }

    2、获取对象不为空的属性

    /**

    * 获取对象不为空的属性

    * @param object

    * @return

    */

    public String getObjectNotNull(Object object) {

    String str = "";

    if (object != null) {

    try {

    Field[] fields = object.getClass().getDeclaredFields();

    for (Field field : fields) {

    if ("serialVersionUID".equals(field.getName())) {

    continue;

    }

    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), object.getClass());

    Method getMethod = pd.getReadMethod();

    Object obj = getMethod.invoke(object);

    if (obj != null && (!StringUtil.isEmpty(obj.toString()))) {

    str += field.getName() + ":" + obj + ";";

    }

    }

    } catch (Exception ex) {

    return ex.toString();

    }

    }

    return str;

    }

    展开全文
  • 5 解析 方式1,采用了最基本的java反射方式,使用Filed,循环bean的Field,得到Object,再转换为Integer类型。 方式2,采用了看似最简洁的BeanUitls,根据属性名,获取属性值。这样最耗时。 方式3,采用了获取bean...

    1 使用field

    long start = System.nanoTime();

    Field[] fields = CallCount.class.getDeclaredFields();

    for (String str : dateList) {

    boolean exist = false;

    for (Field field : fields){

    field.setAccessible(true);

    if (field.getName().endsWith(str)) {

    int value = 0;

    for (CallCount callCount : callCountList) {

    value += (Integer)field.get(callCount);

    }

    resultList.add(value);

    exist = true;

    break;

    }

    }

    if (!exist) {

    resultList.add(0);

    }

    }

    long end = System.nanoTime();

    log.info("old call cost :" + (end-start));

    2 使用 org.apache.commons.beanutils.BeanUtils来获取属性

    long start = System.nanoTime();

    for (String str : dateList) {

    Integer value = getMinuteAccessCount(str, callCountList);

    resultList.add(value);

    }

    long end = System.nanoTime();

    log.info("new call cost :" + (end-start));

    private Integer getMinuteAccessCount(String minute, List callCountList) {

    Integer result = 0;

    String propertyName = "logMinute" + minute;

    for (CallCount callCount : callCountList) {

    int value = 0;

    try {

    value = Integer.valueOf(BeanUtils.getProperty(callCount, propertyName));

    } catch (NumberFormatException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {

    e.printStackTrace();

    }

    result += value;

    }

    return result;

    }

    3 使用java.lang.reflect.Method获取值

    long start = System.nanoTime();

    for (String str : dateList) {

    Integer value = getMinuteAccessCount(str, callCountList);

    resultList.add(value);

    }

    long end = System.nanoTime();

    log.info("new call cost :" + (end-start));

    private Integer getMinuteAccessCount(String minute, List callCountList) {

    Integer result = 0;

    for (CallCount callCount : callCountList) {

    int value = 0;

    try {

    Method method = callCount.getClass().getDeclaredMethod("getLogMinute"+minute);

    Object obj = method.invoke(callCount);

    value = (Integer)obj;

    } catch (NumberFormatException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {

    e.printStackTrace();

    }

    result += value;

    }

    return result;

    }

    4 耗时对比,在使用相同的查询条件,相同的数据的情况下。通过实验得到以下两组数据(耗时/纳秒)

    1 old call cost :517599

    1 old call cost :347916

    1 old call cost :337312

    1 old call cost :177893

    1 old call cost :131709

    1 old call cost :82789

    1 old call cost :63973

    3 new call cost :925383

    3 new call cost :794016

    3 new call cost :912382

    1 old call cost :755016

    1 old call cost :365364

    1 old call cost :231944

    1 old call cost :123498

    1 old call cost :103315

    1 old call cost :92025

    1 old call cost :81762

    2 new call cost :139741338

    2 new call cost :3387140

    2 new call cost :2230497

    2 new call cost :9215854

    2 new call cost :2313970

    2 new call cost :1549374

    2 new call cost :1884291

    2 new call cost :1100880

    2 new call cost :1488138

    每组数据前的数字代表之前取值的方式。

    由数据对比可以看出,耗时最小的,始终是方式1,并且方式1在多次调用时,耗时是逐步减少的,可能是有缓存机制。

    耗时第二少的是方式3,耗时最多的是方式2.

    5 解析

    方式1,采用了最基本的java反射方式,使用Filed,循环bean的Field,得到Object,再转换为Integer类型。 方式2,采用了看似最简洁的BeanUitls,根据属性名,获取属性值。这样最耗时。 方式3,采用了获取bean的Method,然后invoke的方式来获取值。

    展开全文
  • 反射比较两个对象属性值是否改变,并将哪个字段,字段名称,改之前的值,改之后的值入库 话不多说 先上才艺: 工具类代码如下: /** * @Description: 反射获取 两个对象之间的不同属性值 * @Param: old ...
  • packagetest.demo;publicclassStudent{privateStringid;privateStringname;privateintage;privateBooleanisout;publicfinalStringgetId(){returnid;}publicfinalvoidsetId(Stringid){this.id...
  • JAVA反射给属性赋值

    2021-02-27 10:55:26
    开始理解起来可能比较费劲,但我们可以通过一个通俗说明来这样理解AOPJAVA反射——给属性赋值使用反射的机制来给私有的属性赋值,这个原理在许多ORM的组件中都有应用,下面是一段掩饰代码pub...
  • 对此我们可以利用反射设计不同list对象都可以调用筛选的方法,同时实现任意多条件筛选查询。 一、代码实现 代码传参有泛型实体类和泛型数据列表,主要利用反射获取传入实体对象的get方法获取筛选条件,因此筛选的...
  • 当我必须查找方法时,我通常做的是从我正在进行的查询生成缓存键,并将此缓存键保存在地图中.例:我知道方法参数是Boolean.TRUE,Arrays.asList(“foo”,“bar”,“baz”)和BigInteger.valueOf(77777l)我的类包含一个带...
  • 分享一个利用反射实现比较两个实体属性值的方法:package net.zwq1105.test;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.sql.Timestamp;...
  • 今天刷技术文章,遇到了一个问题,用 Java 反射机制去修改 String 变量的值,出于深入研究,就发现了一个问题,即,用初始值比较修改后的值,用 == or .equals() 方法,出现了相等的情况文字描述看起来比较难受,...
  • 可能我们有一个模糊的概念,反射性能会慢,但是有多慢没有一个具体的数据。那我就写代码来测试一下。packagecom.itbac.reflection;importjava.lang.reflect.Field;public classtest {public static void main(String...
  • Java反射和new效率对比

    2021-01-23 14:35:21
    但是随着我们技术的不断提升,我们也学习到了,可以通过反射技术实现对象的创建。 ​ 可是,你有没有想一下,什么时候我们改用new创建对象,什么时候我们改用反射创建对象呢? ​ 两者创建对象的效率又是如何呢? //...
  • 5 解析 方式1,采用了最基本的java反射方式,使用Filed,循环bean的Field,得到Object,再转换为Integer类型。 方式2,采用了看似最简洁的BeanUitls,根据属性名,获取属性值。这样最耗时。 方式3,采用了获取bean...
  • } catch (Exception e) { logger.info("反射取值出错:" + e.toString()); continue; } if (objValue == null) { continue; } if (ms[i].getName().toUpperCase().equals(fieldName.toUpperCase()) || ms[i]....
  • 很多时候,我们需要对两个对象做diff,如果字段一多,比较起来相当的麻烦,利用反射,可以快速的实现一些diff比较,尽量性能不好,这是空间换时间的一些做法。 正文 核心实现如下: /** * * @author Cao Yong * @...
  • 反射性能对比分析

    2021-03-09 08:42:36
    } //反射方式调用 public static void test02()throws NoSuchMethodException, InvocationTargetException,IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1....
  • 性能分析对比 package com.test5; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //分析性能问题 public class test10 { // 普通方法调用 public static void test01...
  • 在Java中通常要比较两个对象在修改前与修改后的值是否相同,一般我们采用的是反射技术获取对象的get方法[或其他的方法]获取值并做比较。如果系统将修改的属性名称也显示出来,这样就能更直观的显示类中的哪一个属性...
  • 反射实例化类 public class Person { public string Name { get; set; } public Person(string name) { this.Name = name; } public string Say(string msg) { return $"{Name}: {msg}"; } } class ...
  • Java 反射与new性能相差几十倍
  • * 本实例意在对比以下两种方法创建对象实例: * 直接new对象 * 反射 * 直接new对象:无法访问SCP类中的私有方法,仅能访问公有方法 * 反射:可访问private,default,protected,public任意方法 * 为...
  • Java各种反射性能对比对各种方法实现get方法的性能进行了一个测试。总共有5个测试,,每个测试都是执行1亿次1. 直接通过Java的get方法2.通过高性能的ReflectAsm库进行测试3.通过Java Class类自带的反射获得Method...
  • 导读这篇文章主要介绍了Java反射获取实例的速度对比分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧之前代码有一个逻辑,是在初始化时读取某个包下的所有class文件,放入到一个HashMap里。...
  • 1. Java反射之性能对比分析 示例: package annoAndRe.reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test08 { //普通方法调用1亿次 public ...
  • /***获取两个对象同名属性内容不相同的列表*@paramclass1对象1*@paramclass2对象2*@return*@throwsClassNotFoundException*@throwsIllegalAccessException*/publicstaticList>compareTwoClass(Objectclass1,...
  • } } 创建运行时类的对象 获取运行时类的完整结构 通过反射获取运行时类的完整结构 Field、Method、Constructor、Superclass、Annotation 实现的全部接口 所继承的父类 全部的构造器 全部的方法 全部的Field 注解 ...
  • 反射实例化类 public class Person { public string Name { get; set; } public Person(string name) { this.Name = name; } public string Say(string msg) { return $"{Name}: {msg}"; } } class Program { //...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 59,086
精华内容 23,634
关键字:

反射对比