反射常见用法:

 Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。

一个实体类

@Data
public class Student {
private String name;
private int color; @Name("方法")
public void sayHello(String Kname) {
this.name = Kname;
System.out.println(Kname);
}
}

Java 反射的主要组成部分有4个:

  • Class:任何运行在内存中的所有类都是该 Class 类的实例对象,每个 Class 类对象内部都包含了本来的所有信息。

  • Field:描述一个类的属性,内部包含了该属性的所有信息,例如数据类型,属性名,访问修饰符······

  • Constructor:描述一个类的构造方法,内部包含了构造方法的所有信息,例如参数类型,参数名字,访问修饰符······

  • Method:描述一个类的所有方法(包括抽象方法),内部包含了该方法的所有信息,与Constructor类似,不同之处是 Method 拥有返回值类型信息,因为构造方法是没有返回值的。

一切java反射操作是基于目标类的类对象完成

java获取这个类对象的三种方式

	//方式一(通过建立对象)
Student stu = new Student() ;
Class classobj1 = stu. getClass();
System.out.print1n(classobj1.getName());
//方式二(所在通过路径-相对路径)
Class classobj2 = Class.forName ("com.gton.entity.Student") ;
System.out.println(classobj2.getName()) ;
//方式三(通过类名)
Class classobj3 = Student.class;
System.out.println(classobj3.getName()) ;

类比拓展java创建对象的几种方式

- 使用关键字  new  调用类的构造函数 创建对象
- 使用反射技术:
Class<?> forName = Class.forName("com.entity.Student");
//JDK1.8 及以前 class.newInstance() 可以实例化一个对象
Student student = (Student) forName.newInstance();
//JDK9之后,包括11
Object newInstance = forName.getDeclaredConstructor().newInstance();
- 使用关键字 clone clone,jvm创建一个实例对象,将数据复制进去,不调用构造函数,实现接口Cloneable,重写 clone方法,clone需要捕获异常
- 反序列化 重文件创建 实现接口Serializable,需要捕获异常 运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法. **具体如下**
// 方法一:new object();
TestOneView first = new TestOneView();
// 方法二:使用Object.clone()
// 因为clone放回的是Object类,所以需要强转一下
TestOneView second = (TestOneView) first.clone();
// 方法三:反射
TestOneView third_1 = (TestOneView) Class.forName("ys.manufacture.ipc.action.TestOneView").newInstance();
TestOneView third_2 = second.getClass().newInstance();
// 方法四:构造方法
TestOneView forth = second.getClass().getConstructor().newInstance();
// 方法五:序列化
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("TestOneView.per"));
outputStream.writeObject(first);
outputStream.writeObject(second);
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("TestOneView.per"));
TestOneView fifth = (TestOneView) inputStream.readObject();

总结创建对象的方法:

1.用new语句创建对象,这是最常用的创建对象的方式。

2.运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。

3.调用对象的clone()方法。

4.运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.

反射基本运用

反射操作这个类

 @SneakyThrows
@Test
public void Star() throws ClassNotFoundException {
Class<?> forName = Class.forName("com.entity.Student");
//利用反射创建对象 JDK1.8 及以前 class.newInstance() 可以实例化一个对象
Student student = (Student) forName.newInstance();
//JDK9之后,包括11
Object newInstance = forName.getDeclaredConstructor().newInstance();
//获取所有的方法
Method[] methods = forName.getMethods();
for (Method method : methods) {
System.out.print(method.getName() + ":");
//反射调用方法
if ("sayHello".equals(method.getName())) {
//获取指定方法:第一个参数方法名。第二个参数是参数类型
Method sayHello = forName.getMethod("sayHello", String.class);
sayHello.invoke(student, "Hello World");
//获取构造器
Constructor<?> constructor = forName.getConstructor();
Student o = (Student) constructor.newInstance();
o.setName("Hello");
System.out.println(o);
//获取get-set
}
}
//获取指定方法:第一个参数方法名。第二个参数是参数类型
Method sayHello = forName.getMethod("setName", String.class);
sayHello.invoke(student, "Hello setName");
System.out.println(student); //获取方法上的注解
sayHello = forName.getMethod("sayHello", String.class);
Name annotation = sayHello.getAnnotation(Name.class);
//获取注解的值
String value = annotation.value();
System.out.println(value); //获取字段
Field[] fields = forName.getDeclaredFields();
for (Field field : fields) {
//属性是私有的,需要设置跳过安全模式取消
field.setAccessible(true);
System.out.println(field);
}
//获取当前本类属性 作用域 属性类型 属性名
Field name = forName.getDeclaredField("name");
System.out.println(name); //生成一个空白的对象
Object newObj = forName.newInstance();
//允许私有属性被操作
name.setAccessible(true);
//反射给这个对象的·私有属性设置值
name.set(newObj, "设置的名字");
System.out.println(newObj);
}

反射的优点:

  • 可扩展性 :应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。

  • 类浏览器和可视化开发环境 :一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。

  • 调试器和测试工具 : 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。

反射的缺点:

尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。

  • 性能开销 :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。

  • 安全限制 :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。

  • 内部暴露 :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。

JavaSE -进阶基础---反射技术的更多相关文章

  1. [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

    [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...

  2. Java基础-反射(reflect)技术详解

    Java基础-反射(reflect)技术详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类加载器 1>.JVM 类加载机制  如下图所示,JVM类加载机制分为五个部分 ...

  3. JavaSE 学习笔记之反射技术(二十四)

    反射技术:其实就是动态加载一个指定的类,并获取该类中的所有的内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员.简单说:反射技术可以对一个类进行解剖. 反射的好 ...

  4. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  5. C#反射技术概念作用和要点

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  6. 【Android测试】【第十七节】Instrumentation——App任你摆布(反射技术的引入)

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处.  转载请注明出处:http://www.cnblogs.com/by-dream/p/5569844.html 前言 学习了上节之后,大家是否已经 ...

  7. C# 反射技术应用

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  8. 用反射技术替换工厂种的switch分支(14)

    首先给大家拜个晚年,祝大家新春快乐,万事如意,鸡年大吉. 好了,前面我们讲了很多的工厂模式,其中,有个很明显的特点,工厂中,有一个方法,里面有很多的swich case  分支,我们前面说过,我们可以 ...

  9. Java基础反射(二)

    原文地址http://blog.csdn.net/sinat_38259539/article/details/71799078 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Cla ...

  10. android中反射技术使用实例

    在计算机科学领域.反射是指一类应用,它们能够自描写叙述和自控制.也就是说,这类应用通过採用某种机制来实现对自己行为的描写叙述(self-representation)和监測(examination), ...

随机推荐

  1. spring的set注入方式流程图解

    spring的set注入方式流程图解 自己学习spring的一些笔记,详细画出了spring的set方式实现依赖注入的流程. 注意:<property name="UserDao&qu ...

  2. C#winform中使用Cef的ChromiumWebBrowser内嵌谷歌内核,调用前端js方法

    1.在winform中调用js方法: --调js中的方法无 入参形式 webBrowser1.ExecuteJavascript("logout()"); --调js中的方法给js ...

  3. Rust-函数

    函数结构 函数要点 函数名和变量名使用蛇形命名法(snake case),例如 fn add_two() -> {} 函数的位置可以随便放,Rust 不关心我们在哪里定义了函数,只要有定义即可 ...

  4. jumpserver设置某个用户登陆后,直接进入指定的服务器,不需要通过导航web终端--我的资产--服务器一连串的展开

    ssh jumpserverUsername@systemUsername@AssetIP@jumpserverHostIP -p2222 解释: - jumpserverUsername:登录 Ju ...

  5. kubernetes kubectl 命令自动补全

    yum install -y bash-completion source /usr/share/bash-completion/bash_completion source <(kubectl ...

  6. Fluentd部署详解

    Fluentd系统配置项 https://www.cnblogs.com/sanduzxcvbnm/p/13920972.html Fluentd自身日志 https://www.cnblogs.co ...

  7. PAT (Basic Level) Practice 1010 一元多项式求导 分数 25

    设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为nxn−1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数).数字间以空格分隔. 输出格式: ...

  8. SQL优化步骤

    当生产数据量急剧增长后,很多SQL语句可能会开始暴露出性能问题.当面对一个有SQL性能问题的数据库时,应该从何处入手进行系统的分析,使得能够尽快定位到问题SQL处并尽快解决问题? 第一步:查看SQL执 ...

  9. python3使用mutagen进行音频元数据处理

    python版本:python 3.9   mutagen版本:1.46.0 mutagen是一个处理音频元数据的python模块,支持多种音频格式,是一个纯粹的python库,仅依赖python标准 ...

  10. Unity——第一人称控制器的实现

    Unity--第一人称控制器的实现 一.功能描述 在一个场景中实现人物的前后左右移动和跳跃功能:其中前后左右移动通过W.A.S.D方向键实现,跳跃功能通过空格键实现,并且考虑到重力作用,来调节跳跃功能 ...