有了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语言访问检查。

package com.chao.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; //动态的创建对象,通过反射
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得Class对象
Class c1 = Class.forName("com.chao.reflection.User");
//构造一个对象
//User user = (User)c1.newInstance(); //本质是调用了类的无参构造器
//System.out.println(user); //通过构造器创建对象
//Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
//User user2 = (User)constructor.newInstance("追梦王子", 001, 18);
//System.out.println(user2); //通过反射调用普通方法
User user3 = (User)c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class); //invoke : 激活的意思
//(对象,"方法的值")
setName.invoke(user3,"追梦王子");
System.out.println(user3.getName()); //通过反射操作属性
System.out.println("8888888888888888888888888888888888");
User user4 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true).
name.setAccessible(true);
name.set(user4,"追梦王子2");
System.out.println(user4.getName()); }
}

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

package com.chao.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//分析性能问题
public class Test10 {
//普通方式调用
public static void test01(){
User user = new User();
long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) {
user.getName();
} long endTime = System.currentTimeMillis();
System.out.println("普通方式执行10亿次:"+(endTime-startTime)+"ms");
}
//反射方式调用
public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) {
getName.invoke(user,null);
} long endTime = System.currentTimeMillis();
System.out.println("反射方式执行10亿次:"+(endTime-startTime)+"ms");
}
//反射方式调用 关闭检测
public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) {
getName.invoke(user,null);
} long endTime = System.currentTimeMillis();
System.out.println("关闭检测执行10亿次:"+(endTime-startTime)+"ms");
} public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test01();
test02();
test03();
}
}

动态的创建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. c++ DWORD和uintptr_t

    x86模式 DWORD 是4字节 x86模式 uintptr_t 是4字节 x64模式 DWORD 是4字节 x64模式 uintptr_t 是8字节 std::cout << sizeo ...

  2. 聊一下PBN程序图例中的XTT

       PBN航路点的定位容差用XTT与ATT来表示,ATT=0.8*XTT.保护区半宽用1.5*XTT+BV计算得到,BV值在不同的航段取值不同. 对于A至E类航空器,距ARP 30nm以外BV值为2 ...

  3. django中间件介绍

    在学习django中间件之前,先来认识一下django的生命周期,如下图所示: django生命周期:浏览器发送的请求会先经过wsgiref模块处理解析出request(请求数据)给到中间件,然后通过 ...

  4. RTPS解析

    资料参考: https://blog.csdn.net/HBS2011/article/details/102520704

  5. pytorch中修改后的模型如何加载预训练模型

    问题描述 简单来说,比如你要加载一个vgg16模型,但是你自己需要的网络结构并不是原本的vgg16网络,可能你删掉某些层,可能你改掉某些层,这时你去加载预训练模型,就会报错,错误原因就是你的模型和原本 ...

  6. 手把手教你Centos7 部署 gitlab社区版

    一.前置说明: 操作系统:Centos 7 物理内存:>=2G 本人亲测,如果安装低版本的gitlab,比如我这里所使用的v8.17.0,物理内存1G,swap 2G虚拟内存即可部署.高版本的所 ...

  7. ============================================ 微信小程序开发学习

    开发文档: https://developers.weixin.qq.com/miniprogram/dev/framework/

  8. 如果要是把标记为2的那一行Lable1.Text改为其他的Lable显示执行代码

    转: 如果要是把标记为2的那一行Lable1.Text改为其他的Lable显示执行代码 如图,程序很简单,文件路径也没问题,为什么会报错,百思不得其解?[url]https://book.douban ...

  9. 一个 java 文件的执行过程详解

    平时我们都使用 idea.eclipse 等软件来编写代码,在编写完之后直接点击运行就可以启动程序了,那么这个过程是怎么样的? 总体过程 我们编写的 java 文件在由编译器编译后会生成对应的 cla ...

  10. Graylog日志管理单机部署、日志节点的Sidecar配置以及简单的警告事件邮件发送

    应该是上个星期的上个星期,下了个任务,要做Graylog的部署以及文档,emmm....带log,肯定是和日志有关系了呗,不过也没听过啊,去搜了一下,确实,也不少帖子博客相关的都有安装部署,还是yum ...