有了Class对象,能做什么?

  • 创建类的对象:调用Class对象的newInstance()方法

    • 类必须有一个无参数的构造器。

    • 类的构造器的访问权限需要足够。

思考?没有无参的构造器就不能创建对象吗?只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。

  • 如下

    • 通过Class类的getDeclaredConstructor(Class ... parameterTypes)取得本类的指定形参类型的构造器

    • 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数

    • 通过Constructor实例化对象

调用指定的方法

通过反射,调用类中的方法,通过Method类完成。

  • 通过Class类的getMethod(String name,Class...parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。

  • 之后使用Object invoke(Object obj,Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

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

  • Object对应原方法的返回值,若原方法无返回值,此时返回null。

  • 若原方法若为静态方法,此时形参Object obj可为null。

  • 若原方法形参列表为空,则Object[] args为null。

  • 若原方法声明为private,则需要在调用此invoke()方法前,显示调用方法对象的setAccessible(true)方法,将可访问private的方法。

setAccessible

  • Method和Field、Constructor对象都有setAccessible()方法。

  • setAccessible作用是启动和禁用访问安全检查的开关。

  • 参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。

    • 提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。

    • 使得原本无法访问的私有成员也可以访问。

  • 参数值为false则指示反射的对象应该实施Java语言访问检查。

  1. package com.chao.reflection;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. //动态的创建对象,通过反射
  7. public class Test09 {
  8. public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
  9. //获得Class对象
  10. Class c1 = Class.forName("com.chao.reflection.User");
  11. //构造一个对象
  12. //User user = (User)c1.newInstance(); //本质是调用了类的无参构造器
  13. //System.out.println(user);
  14. //通过构造器创建对象
  15. //Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
  16. //User user2 = (User)constructor.newInstance("追梦王子", 001, 18);
  17. //System.out.println(user2);
  18. //通过反射调用普通方法
  19. User user3 = (User)c1.newInstance();
  20. //通过反射获取一个方法
  21. Method setName = c1.getDeclaredMethod("setName", String.class);
  22. //invoke : 激活的意思
  23. //(对象,"方法的值")
  24. setName.invoke(user3,"追梦王子");
  25. System.out.println(user3.getName());
  26. //通过反射操作属性
  27. System.out.println("8888888888888888888888888888888888");
  28. User user4 = (User)c1.newInstance();
  29. Field name = c1.getDeclaredField("name");
  30. //不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true).
  31. name.setAccessible(true);
  32. name.set(user4,"追梦王子2");
  33. System.out.println(user4.getName());
  34. }
  35. }

调用方式的性能分析----代码

  1. package com.chao.reflection;
  2. import java.lang.reflect.InvocationTargetException;
  3. import java.lang.reflect.Method;
  4. //分析性能问题
  5. public class Test10 {
  6. //普通方式调用
  7. public static void test01(){
  8. User user = new User();
  9. long startTime = System.currentTimeMillis();
  10. for (int i = 0; i < 1000000000; i++) {
  11. user.getName();
  12. }
  13. long endTime = System.currentTimeMillis();
  14. System.out.println("普通方式执行10亿次:"+(endTime-startTime)+"ms");
  15. }
  16. //反射方式调用
  17. public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  18. User user = new User();
  19. Class c1 = user.getClass();
  20. Method getName = c1.getDeclaredMethod("getName", null);
  21. long startTime = System.currentTimeMillis();
  22. for (int i = 0; i < 1000000000; i++) {
  23. getName.invoke(user,null);
  24. }
  25. long endTime = System.currentTimeMillis();
  26. System.out.println("反射方式执行10亿次:"+(endTime-startTime)+"ms");
  27. }
  28. //反射方式调用 关闭检测
  29. public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  30. User user = new User();
  31. Class c1 = user.getClass();
  32. Method getName = c1.getDeclaredMethod("getName", null);
  33. getName.setAccessible(true);
  34. long startTime = System.currentTimeMillis();
  35. for (int i = 0; i < 1000000000; i++) {
  36. getName.invoke(user,null);
  37. }
  38. long endTime = System.currentTimeMillis();
  39. System.out.println("关闭检测执行10亿次:"+(endTime-startTime)+"ms");
  40. }
  41. public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
  42. test01();
  43. test02();
  44. test03();
  45. }
  46. }

动态的创建Class对象方法及调用方式性能分析的更多相关文章

  1. Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)

    Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...

  2. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  3. 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...

  4. Java中对象方法的调用过程&动态绑定(Dynamic Binding)

    Java面向对象的最重要的一个特点就是多态, 而多态当中涉及到了一个重要的机制是动态绑定(Dynamic binding). 之前只有一个大概的概念, 没有深入去了解动态绑定的机理, 直到很多公司都问 ...

  5. 使用type在对象方法中调用类方法

    type简介 type在Python中的作用是创建一个类. 我们创建类的时候一般会使用这样的方法: # -*- coding:utf-8 -*- class Student(object): coun ...

  6. Java反射机制(创建Class对象的三种方式)

    1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Fi ...

  7. Java反射机制(创建Class对象的三种方式)

    1:了解什么是反射机制? 在通常情况下,如果有一个类,可以通过类创建对象:但是反射就是要求通过一个对象找到一个类的名称:   2:在反射操作中,握住一个核心概念: 一切操作都将使用Object完成,类 ...

  8. spring中创建bean对象的三种方式以及作用范围

    时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...

  9. JDBC 创建连接对象的三种方式 、 properties文件的建立、编辑和信息获取

    创建连接对象的三种方式 //第一种方式 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ ...

随机推荐

  1. 千万不要错过VAST,NGK算力的下一个财富机会!

    我们把目光投向NGK市场,近来,NGK接连新币,推出了SPC后,又有VAST.在目前市场上债券收益率已经趋近于零的情况下,世界上的大多数央行都在试图让本国货币贬值,所以在此时寻找其他保值资产是合理的. ...

  2. SPC空投糖果,是白捡还是风险?

    2020年,币圈刮起了空投风,很多项目纷纷"撒钱"在空投中,在空投中获利多者白捡上百万美刀,少的也薅了万把块羊毛,币圈的空投无时不刻透露着天上掉馅饼的气息.NGK官方在2020年年 ...

  3. flex图片垂直居中

    html <view class="person_info_more"> <image class="more" src="/ima ...

  4. Django Admin 在内联中覆盖保存方法(admin.TabularInline)

    一  使用环境 开发系统: windows IDE: pycharm 数据库: msyql,navicat 编程语言: python3.7  (Windows x86-64 executable in ...

  5. Navicat Premium的数据传输功能----将远程Mysql数据库复制到本地数据库的方法

    1.先连上本地.远程的数据库 2.在本地建一个和你要复制的远程数据库的名称一样的数据库 3.数据转移.工具-->数据传输-->填写源数据库和目标数据库-->下一步-->开始 注 ...

  6. ERROR 1040 (HY000) Too many connections

    C:\Users\Jilil>mysql -u root -pEnter password: *************ERROR 1040 (HY000): Too many connecti ...

  7. Redis操作指南

    目录 Redis安装与使用教程 一.Redis介绍 1.redis安装 2.redis与mysql的异同 3.redis与memcache的异同 二.Redis操作 1.启动服务 2.密码管理 3.连 ...

  8. JAVA基础(零)—— 踩坑与错误(常更)

    JAVA基础(零)-- 踩坑与错误(常更) 1 坑 考虑输入为null的情况 自动转换 x/Math.pow(10,i)*Math.pow(10,i) //由于math.pow()返回double类型 ...

  9. TorchVision Faster R-CNN 微调,实战 Kaggle 小麦检测

    本文将利用 TorchVision Faster R-CNN 预训练模型,于 Kaggle: 全球小麦检测 上实践迁移学习中的一种常用技术:微调(fine tuning). 本文相关的 Kaggle ...

  10. Java变量-常量-作用域

    public class Demo05 { /* 变量的命名规范:见名知意 1.类变量/实例变量/局部变量使用驼峰原则命名 2.类名使用Pascal命名法 3.常量名使用大写字母和下划线 4.驼峰原则 ...