精华内容
下载资源
问答
  • 反射角度讲反射

    2020-05-17 17:06:04
    大家好,我是反射。想必有些人已经认识我很久了,但是也有很多朋友并不认识我,所有我还是先给大家做一下简单的自我介绍。简单的说,我是一种武器,是给一种叫做程序员角色用来打boss(直聘)用的,并且我在java的大...
    	大家好,我是反射。想必有些人已经认识我很久了,但是也有很多朋友并不认识我,所有我还是先给大家做一下简单的自我介绍。简单的说,我是一种武器,是给一种叫做程序员角色用来打boss(直聘)用的,并且我在java的大家庭中也是至关重要的一员,我的作用就是可以动态的创建类的对象。
    众所周知,我们在写java程序的时候,都是基于对象来编程的。所以我们在写代码的时候都要先创建某些类的对象。大多数情况我们写编写好程序之前都已经把所有对象的类都定义好了。当我们需要使用该对象时直接使用new关键字new 出来就好了。但是随着我们编程的环境越开越复杂,避免不了我们在程序编译时,没有办法获取到该对象的class文件,需要程序运行时期通过网络等形式进行获取。这个时候我们该如何创建出我们需要使用的对象呢。这个时候就需要反射来登场了。下面我们来看一段代码。
    
    public class Demo {
    	public static void main(String[] args) throws Exception {
    		//读取配置文件
    		BufferedReader br = new BufferedReader(new FileReader("config.txt"));
    		String classpath = br.readLine();//com.sunwhite.codeidea.reflect.demo.Person
    
    		//根据读到的类路径创建对象
    		Class clazz = Class.forName(classpath);
    		//用反射的方式便捷的创建一个类的实例  依赖的是无参的构造方法
    		Object obj = clazz.newInstance();//实例化不了  Person类里面没有无参的构造方法了
    
    		System.out.println(obj);
    
    //		Person  p = new Person();//类 ---对象   汽车的设计图纸   ----汽车
    	}
    }
    
    	从上边的代码中我们可以看到我们创建了一个obj对象,他其实是一个person对象,但是在程序编译时期我们并不需要事先定义好Person类,这就极大的扩展了我们java语言的灵活性。我们可以在程序运行的时候根据运行需求再来获取或者定义我们编写类的具体内容。
    别忘了我们的终极目的,是为了调用一个动态类的api,我们有了obj对象之后如何获取他的方法并且调用他呢?Class类与java.lang.relect类库给我们提供了支持。在relect类库中包含了Filed,Methed,Constructor类,他们每个类都实现的Member接口,代表他们是属于一个类的成员。这些类的对象是由jvm在运行时间创建的,用以表示未知类里对应的成员。这样我们就可以使用Constructors来创建对象,使用Field对象的get()和set()方法获取或者修改对象属性的值,使用Method对象的invoke调用对象的api。代码示例见如下。
    
    		Constructor[] constructors = clazz.getConstructors();//获取构造方法
    		constructors[0].newInstance();//使用构造对象创建实例
    
    		Field[] fields = clazz.getFields();
    		Field name = clazz.getField("name");
    		name.set(obj,"张三");
    
    		Method[] methods = clazz.getMethods();
    		Method toString = clazz.getMethod("toString", clazz);
    		toString.invoke(obj);
    
    		重要的是,要认识到反射机制并没有神器之处,他只是提供了一种方式让我们调用对象的所有方法。而对于反射机制来说,.class文件在编译时是不可以获取的,是在运行时打开和检查.class文件的。
    		反射机制还有另外一个优势,从外部获取的class文件,需要本着以诚相待的外部开到jvm,所以反射可以通过带有Declared的方法获取的该类的所有的成员对象包括private修饰符权限修饰的属性,方法和构造方法,这并不算违反了类的基本类权。
    		![在这里插入图片描述](https://img-blog.csdnimg.cn/20200517154436307.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODU0ODgwMg==,size_16,color_FFFFFF,t_70#pic_center)
    
    		我们在利用反射进行编程的时候通常是以动态代理的方式进行使用的。代理是基本的设计模式之一,它是为了提供额外的货不同的操作,代替实际对象的的对象。这些操作通常设计与实际对象的通信。举个例子,有一个小孩对象,非常喜欢吃东西,会有吃鸡,吃水果等行为,他的爸爸每次吃东西前都会给他洗手,所以每次妈妈让小孩吃东西时都会把食物给到爸爸,爸爸就相当于小孩子的代理。相对于吃东西,洗手就是一个额外的操作,它既不影响小孩子执行吃东西的行为,又做到了安全的保障。我们在实现这个逻辑的时候,在每个吃东西的行为上都写上一段洗手的逻辑,显然是不符合我们代码复用的基本编码规则的。那么我们该如何处理呢?请看下边这段代码。
    
    package com.pattern.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyMain2 {
    
        public static void main(String[] args) {
            Children baby = new Baby();
            Dad dad = new Dad(baby);
            //使用java的动态代理方式创建代理
            Children $dad = (Children)Proxy.newProxyInstance(baby.getClass().getClassLoader(), baby.getClass().getInterfaces(), dad);
            $dad.eatChicken();
            $dad.eatFruits();
            $dad.cry();
        }
    }
    //必须要有孩子的爸爸,因为需要代理孩子
    class Dad implements InvocationHandler {
        private Children children;
    
        public Dad(Children children){
            this.children=children;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           //判断孩子是否要吃东西
            if (method.getName().indexOf("eat")!=-1){
                wash();
                method.invoke(children,args);//使用反射的方式执行方法
            }
    
            return null;
        }
    
        private void wash(){
            System.out.println("洗手");
    
        }
    }
    
    //小孩接口
    interface Children{
        void eatChicken();
    
        void eatFruits();
    
        void cry();
    }
    
    class Baby implements  Children{
        @Override
        public void eatChicken() {
            System.out.println("吃鸡肉");
        }
    
        @Override
        public void eatFruits() {
            System.out.println("吃水果");
        }
    
        @Override
        public void cry() {
            System.out.println("哭");
        }
    }
    
    	在这段代码中我们在dad类中使用了反射的方式执行Method。这让我们使用了动态代理成为了可能。InvocationHandler是baby通知,当baby在执行方法时,jvm会向InvocationHandler的实现既Dad发送通知,`Children $dad = (Children)Proxy.newProxyInstance(baby.getClass().getClassLoader(), baby.getClass().getInterfaces(), dad);`
    	从这行代码中我们可以看到jvm将Children下的接口和InvocationHandler的实现Dad绑定在了一起,从而实现dad对baby的监控。
    	知道了这些对我们的编程中有什么?我们知道在我们进行代码重构的过程中通常会抽取公用的方法,抽取的时候通常是从横向和纵向进行抽取的。纵向说的就是多个服务用到了同一段数据处理逻辑,这个时候我们通过纵向抽取的方式抽出到单独的方法,让多个服务共同调用,提高代码的可维护性。但是有些逻辑的代码的公用程度很高,比如方法访问的权限和日志,事务处理等逻辑。让所有的方法都去调用一遍都显的既麻烦又冗余。那么我们就可以通过创建切面,然后使用动态代理的方式,去对代码进行增强。
    
    展开全文
  • 在分析金属反射镜和多层周期反射镜优缺点的基础上,介绍了一维光子晶体出现全偏振全角度反射的原理。讨论了增加禁带宽度的方法及一维光子晶体全角度反射镜中存在的问题。
  • 其太阳观测端口的透过率和太阳漫射板的相对双向反射分布函数(BRDF)是随角度变化的变量,因此比辐射计观测信号会受到入射光线角度的影响,该影响因子被叫作比辐射计角度因子(简称角度因子)。提出一种使用星上数据计算...
  • 根据角域叠加原理,在石英玻璃基板上用全介质膜系实现了紫外区域全角度一维光子晶体反射镜的设计。采用两个不存在全角度反射带的一维光子晶体在角域上叠加,通过传输矩阵方法,从理论上计算合成光子存在全角度禁带,禁带...
  • 为了简化手术灯照明系统的光学结构, 设计了一种新型宽入射角调色温冷反射镜。分析了医学手术灯的光谱技术要求, 分别使用三角垂直插值法计算光源系统的相关色温和标准三刺激值计算法计算显色指数编制程序计算。对比一...
  • 为了进一步提高反射率差分型生物传感器的检测灵敏度,提出通过双入射角度的方法来实现反射率差分检测。该方法将入射光束调至能够使单位生物膜层厚度反射率差分量最大的两个角度去照射实验样品,通过接收端测得的反射...
  • 基于多光束干涉原理, 从高斯光束在自由空间的传输方程出发, 推导了高斯光束斜入射角度调谐窄带滤光片的反射光强以及透射光强的表达式。在此基础上研究了滤光片入射角对高斯光束反射特性的影响和关系。理论数值计算和...
  • 对用于193 nm减反射膜的基底材料和薄膜材料的光学性能进行了解析,同时对沉积技术和主要沉积工艺参数进行了分析与优化选择,并在此基础上进行了193 nm大角度入射减反射膜的设计、制备及检测,实现了入射角为68°~72...
  • 从安全角度谈Java反射机制--前章

    千次阅读 2020-05-07 17:07:50
    从安全角度谈Java反射机制第二章,从代码执行角度剖析Java反射机制。

    前言

    首发:https://www.sec-in.com/article/307
       欢迎回来,上回说到Java反射机制基础知识,并用简单代码做了一个简单的Demo。
      笔者从执行命令的角度来展开话题,看这篇文章大部分都是网络安全的从业者亦或者是安全规范的学习者,众所周知执行命令获取权限是安全人员追求,也是黑客最终追求。所以从执行命令的角度来展开,无疑是激发你们读者最大阅读兴趣。

    ps: 本文实验代码都上传JavaLearnVulnerability项目,为了让更多人知道,麻烦动动小手star一下。


    知识补充

       这里稍微补充一点小知识,对于一些0基础的读者的一些知识补充,老司机可以忽视。Java执行命令常见的有两个类java.lang.Runtimejava.lang.ProcessBuilder,通常情况下使用java.lang.Runtime类,个人觉得Runtime类是比ProcessBuilder好使用些。

    windows下执行命令的几种方式

    1. Windows下调用程序

    Process proc =Runtime.getRuntime().exec(“exefile”);

    1. Windows下调用系统命令

    String [] cmd={“cmd”,"/C",“copy exe1 exe2”};
    Process proc =Runtime.getRuntime().exec(cmd);

    1. Windows下调用系统命令并弹出命令行窗口

    String [] cmd={“cmd”,"/C",“start copy exe1 exe2”};
    Process proc =Runtime.getRuntime().exec(cmd);

    Linux下执行命令的几种方式

    1. Linux下调用程序

    Process proc =Runtime.getRuntime().exec("./exefile");

    1. Linux下调用系统命令

    String [] cmd={"/bin/sh","-c",“ln -s exe1 exe2”};
    Process proc =Runtime.getRuntime().exec(cmd);

    1. Linux下调用系统命令并弹出命令行窗口

    String [] cmd={"/bin/sh","-c",“xterm -e ln -s exe1 exe2”};
    Process proc =Runtime.getRuntime().exec(cmd);


    反射之Runtime

    在这里插入图片描述

    方法一

    Object ob = cls.getMethod(“getRuntime”,null).invoke(null,null);
    返回的是一个Runtime类对象
    前文说过,invoke第一个参数是一个Object类对象
    你可能好奇为什么我不直接使用newInstance()呢?
    因为Runtime类中的无参构造方法是private权限,无法访问。ps:其实是有办法的,下文会说道。
    getRuntime方法返回的是Runtime类对象,这就是为什么有些payload会使用此方法了,而不是直接newInstanc()

    在这里插入图片描述

    public static void Method1(){
            try {
                //获取对象
                Class cls = Class.forName("java.lang.Runtime");
                //实例化对象
                Object ob = cls.getMethod("getRuntime",null).invoke(null,null);
                // 反射调用执行命令
                cls.getMethod("exec", String.class).invoke(ob,"calc");
    
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    

    方法二

    前文说过java.lang.Runtime类无参构造方法是private权限无法直接调用
    setAccessible通过反射修改方法的访问权限,强制可以访问
    Constructor constructor = cls.getDeclaredConstructor();是获取类构造器方法的方法

     public static void Method2(){
            try {
                // 获取对象
                Class cls = Class.forName("java.lang.Runtime");
                // 获取构造方法
                Constructor constructor = cls.getDeclaredConstructor();
                
                constructor.setAccessible(true);
                // 实例化对象
                Object ob = constructor.newInstance();
                Method mt = cls.getMethod("exec", String.class);
    
                mt.invoke(ob,"calc");
    
    
            } catch (ClassNotFoundException | NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    

    反射之ProcessBuilder

    在这里插入图片描述

    通过看JDK文档,ProcessBuilder类有两个构造方法。
    在这里插入图片描述
    如果分别使用反射构造方法获取实例化语句如下:

    • Class.forName("java.lang.ProcessBuilder").getDeclaredConstructor(List.class).newInstance(Arrays.asList("calc")))
    • Class.forName("java.lang.ProcessBuilder").getDeclaredConstructor(String.class).newInstance("calc"))

    方法一

       方法一笔者在此就提一点,newInstance()实例化时把所需要执行命令参数直接一并进行了。

    public static void Method1(){
            try {
                // 获取对象
                Class cls = Class.forName("java.lang.ProcessBuilder");
                // 实例化对象
                Object ob = cls.getDeclaredConstructor(List.class
                ).newInstance(Arrays.asList("calc"));
                // 执行命令
                cls.getMethod("start").invoke(ob,null);
    
            } catch (ClassNotFoundException | NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    

    方法二

       方法二使用第二种构造方法,可变长参数(String...表示参数长度不确定)。那么对于反射来说,如果要获取目标函数里包含的可变长参数,可直接视为数组。因此只需要将String [].class传给构造方法即可,但在调用newInstance()实例化方法时,不能直接传一个一维数组String[]{“calc"},而是应该传入一个二维数组String[][]{{"calc"}}。因为newInstance()函数本身接收的是一个可变长参数,我们传给ProcessBuilder的也是一个可变长参数,二者叠加由一维数组变成了二维数组。

    public static void Method2(){
            try {
                // 获取对象
                Class cls = Class.forName("java.lang.ProcessBuilder");
                // 实例化对象
                
                String[][] cls2 = new String[][]{{"calc"}};
                Object ob = cls.getConstructor(String[].class).newInstance(cls2);
                //执行命令
                cls.getMethod("start").invoke(ob,null);
    
            } catch (ClassNotFoundException | NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    

    参考

    https://xz.aliyun.com/t/7029#toc-3
    https://javasec.org/javase/Reflection/Reflection.html
    JDK文档
    Java安全漫谈-反射篇 --P牛著。

    展开全文
  • 设计了一种基于角度多普勒分辨的接发同轴反射层析激光成像雷达系统,给出了基本成像原理和数学表达,相应分析了目标横向距离分辨率和单个角度采样时间的关系。并在实验室平台上模拟远场衍射传输,获取探测目标的角度...
  • 为了解决上述问题本课题基于光学内 反射效应,设计并试制了一种能够弥补传统测角仪器上述不足的新型二维微小角 度传感器,实现二维角度的测量,为下一步设计出多自由度位移检测系统,实现 对精密加工机床或坐标测量...
  • java 反射

    2020-04-03 01:06:02
    动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数... 从反射角度说 JAVA 属于半动态语言。 反射机制概念 (运行状态中知道类所有的属性和方法) 在 Java 中的反射机制是指在运行状态中,对于任意一...

    动态语言

    动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化。比如常见的 JavaScript 就是动态语言,除此之外 Ruby,Python 等也属于动态语言,而 C、 C++则不属于动态语言。 从反射角度说 JAVA 属于半动态语言。
     

    反射机制概念 (运行状态中知道类所有的属性和方法)

    在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为 Java 语言的反射机制。
     

    反射的应用场合

    在 Java 程序中许多对象在运行是都会出现两种类型:编译时类型和运行时类型。 编译时的类型由声明对象时实用的类型来决定,运行时的类型由实际赋值给对象的类型决定 。 如:
    Person p=new Student();
    其中编译时类型为 Person,运行时类型为 Student。

    程序在运行时还可能接收到外部传入的对象, 该对象的编译时类型为 Object,但是程序有需要调用该对象的运行时类型的方法。为了解决这些问题, 程序需要在运行时发现对象和类的真实信息。然而,如果编译时根本无法预知该对象和类属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须使用到反射了。

    举例:传一串字符串,根据字符串动态创建出,此刻需要的对象

    传统做法:

    public Object function(String path){
                  if(path.equals("java.io.File")){
                       return new File("xxx");
                     }else if(path.equals("java.lang.Intager")){
                    return new Intager(0);
                 ......}
    使用反射 : 

    public Object function(String path){
                    try{
                        return Class.forNmae(“xx”).newInstance();
             }catch(Exception e){
    .....
    }
                 }
    很显然后者更简单,可扩张性更好。


    这个在写框架中有比较广泛的使用,比如Hibernate。 Hibernate是如何将SQL查询出来的结果放进对象中的呢,其实就是调用pojo中的set方法,然而,hibernate不会知道你有多少属性,也不会知道有多少的set方法,这里就是使用反射回去到类中的方法,将执行相关的set方法将结果保存进对象。

     

    Java 反射 API

    反射 API 用来生成 JVM 中的类、接口或则对象的信息。
    1. Class 类:反射的核心类,可以获取类的属性,方法等信息。
    2. Field 类: Java.lang.reflec 包中的类, 表示类的成员变量,可以用来获取和设置类之中的属性值。
    3. Method 类: Java.lang.reflec 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
    4. Constructor 类: Java.lang.reflec 包中的类,表示类的构造方法。

     

    反射使用步骤(获取 Class 对象、调用对象方法)

    1. 获取想要操作的类的 Class 对象,他是反射的核心,通过 Class 对象我们可以任意调用类的方法。
    2. 调用 Class 类中的方法,既就是反射的使用阶段。
    3. 使用反射 API 来操作这些信息。

     

    获取 Class 对象的 3 种方法

    • 调用某个对象的 getClass()方法

    Person p=new Person();
    Class clazz=p.getClass();

    • 调用某个类的 class 属性来获取该类对应的 Class 对象

    Class clazz=Person.class;

    • 使用 Class 类中的 forName()静态方法(最安全/性能最好)

    Class clazz=Class.forName("类的全路径"); (最常用)
    当我们获得了想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法
    和属性。

    //获取 Person 类的 Class 对象
    Class clazz=Class.forName("reflection.Person");
    
    //获取 Person 类的所有方法信息
    Method[] method=clazz.getDeclaredMethods();
    for(Method m:method){
    System.out.println(m.toString());
    }
    
    //获取 Person 类的所有成员属性信息
    Field[] field=clazz.getDeclaredFields();
    for(Field f:field){
    System.out.println(f.toString());
    }
    //获取 Person 类的所有构造方法信息
    Constructor[] constructor=clazz.getDeclaredConstructors();
    for(Constructor c:constructor){
    System.out.println(c.toString());
    }

    创建对象的两种方法

    • Class 对象的 newInstance()

    1. 使用 Class 对象的 newInstance()方法来创建该 Class 对象对应类的实例,但是这种方法要求该 Class 对象对应的类有默认的空构造器。

    • 调用 Constructor 对象的 newInstance()

    2. 先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance()方法来创建 Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。

    //获取 Person 类的 Class 对象
    Class clazz=Class.forName("reflection.Person");
    
    //使用.newInstane 方法创建对象
    Person p=(Person) clazz.newInstance();
    
    //获取构造方法并创建对象
    Constructor c=clazz.getDeclaredConstructor(String.class,String.class,int.class);
    
    //创建对象并设置属性
    Person p1=(Person) c.newInstance("李四","男",20);

     

    展开全文
  • 基于多块光栅拼接理论,建立了光栅旋转角与衍射光束偏角关系的数学模型,设计了一种基于干涉法的光栅旋转角度检测光路,用Zygo干涉仪实现了光栅0级与1级衍射波前检测,并研究了反射镜安装误差引起的模型误差。...
  • JAVA反射

    2020-03-09 14:01:19
    动态语言 动态语言,是指程序在运行时可以改变其结构:新的...从反射角度说 JAVA 属于半动态语言。 反射机制概念 (运行状态中知道类所有的属性和方法) 在 Java 中的反射机制是指在运行状态中,对于任意一个类...

    动态语言

    动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结
    构上的变化。比如常见的 JavaScript 就是动态语言,除此之外 Ruby,Python 等也属于动态语言,
    而 C、C++则不属于动态语言。从反射角度说 JAVA 属于半动态语言。

    反射机制概念 (运行状态中知道类所有的属性和方法)

    在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;
    并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方
    法的功能成为 Java 语言的反射机制。

     

    在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;
    并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方
    法的功能成为 Java 语言的反射机制。

     

    编译时类型和运行时类型


    在 Java 程序中许多对象在运行是都会出现两种类型:编译时类型和运行时类型。 编译时的类型由
    声明对象时实用的类型来决定,运行时的类型由实际赋值给对象的类型决定 。如:
    Person p=new Student();
    其中编译时类型为 Person,运行时类型为 Student。

     

    程序在运行时还可能接收到外部传入的对象,该对象的编译时类型为 Object,但是程序有需要调用
    该对象的运行时类型的方法。为了解决这些问题,程序需要在运行时发现对象和类的真实信息。
    然而,如果编译时根本无法预知该对象和类属于哪些类,程序只能依靠运行时信息来发现该对象的编译时类型无 法获取具体方法

    和类的真实信息,此时就必须使用到反射了。

     

    Java 反射 API

    反射 API 用来生成 JVM 中的类、接口或则对象的信息。
    1.  Class 类:反射的核心类,可以获取类的属性,方法等信息。
    2.  Field 类:Java.lang.reflec 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性
    值。
    3.  Method 类: Java.lang.reflec 包中的类,表示类的方法,它可以用来获取类中的方法信息或
    者执行方法。
    4.  Constructor 类: Java.lang.reflec 包中的类,表示类的构造方法。

     

    反射使用步骤(获取 Class 对象、调用对象方法)

    1.  获取想要操作的类的 Class 对象,他是反射的核心,通过 Class 对象我们可以任意调用类的方
    法。
    2.  调用 Class 类中的方法,既就是反射的使用阶段。
    3.  使用反射 API 来操作这些信息。

    获取 Class 对象的 3 种方法

     

    调用某个对象的 getClass() 方法
    Person p=new Person();
    Class clazz=p.getClass();


    调用某个类的 class 属性来获取该类对应的 Class 对象
    Class clazz=Person.class;


    使用 Class 类中的 forName() 静态方法 ( 最安全 / 性能最好 )
    Class clazz=Class.forName("类的全路径"); (最常用)

    当我们获得了想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法
    和属性

    //获取 Person 类的 Class 对象
    Class clazz=Class.forName("reflection.Person");
    //获取 Person 类的所有方法信息
    Method[] method=clazz.getDeclaredMethods();
    for(Method m:method){
    System.out.println(m.toString());
    }
    //获取 Person 类的所有成员属性信息
    Field[] field=clazz.getDeclaredFields();
    for(Field f:field){
    System.out.println(f.toString());
    }
    //获取 Person 类的所有构造方法信息
    Constructor[] constructor=clazz.getDeclaredConstructors();
    for(Constructor c:constructor){
    System.out.println(c.toString());
    }

     

    创建对象的两种方法

    Class 对象的 newInstance()
    1.  使用 Class 对象的 newInstance()方法来创建该 Class 对象对应类的实例,但是这种方法要求
    该 Class 对象对应的类有默认的空构造器。
    调用 Constructor 对象的 newInstance()
    2.  先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance()
    方法来创建 Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。

    //获取 Person 类的 Class 对象
    Class clazz=Class.forName("reflection.Person");
    //使用.newInstane 方法创建对象
    Person p=(Person) clazz.newInstance();
    //获取构造方法并创建对象
    Constructor c=clazz.getDeclaredConstructor(String.class,String.class,int.class);
    //创建对象并设置属性
    Person p1=(Person) c.newInstance("李四","男",20);

     

    展开全文
  • Java反射

    2021-03-07 21:43:16
    程序运行时可改变其结构,比如常见的 JavaScript,Python 等,从反射角度来说 Java 属于半动态语言。 概念 在运行状态中,对于任意一个类都能知道这个类所有的属性和方法,并且对于任意一个对象都可以调用它的任意一...
  • JAVA 反射

    2020-12-10 14:05:48
    反射角度说 JAVA 属于半动态语言。 2. 标题反射机制概念 (运行状态中知道类所有的属性和方法) 在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法; 并且对于任意一个对象...
  • 对于三端口角度调谐薄膜滤波器,反射端口的特性对于反射多波长光谱非常重要。当滤光片处于倾斜入射状态时,反射光束会变宽,反射率会降低。本文提出了一种基于快速傅里叶变换和菲涅尔公式的频率递归算法。利用该频率...
  • 应用于硬X射线波段的宽带多层膜光学元件——宽角度X射线超反射镜的设计可以归结为一个连续变量的多维多极值的全局优化问题。缺少一种有效的全局优化方法是阻碍解决这一难题的一个关键。模拟退火算法是一种简单而且...
  • 从安全角度谈Java反射机制--终章

    千次阅读 2020-05-07 17:07:36
    从安全角度谈Java反射机制,深入了解SSTI的payload的构造方法。
  • 文章目录反射reflect1 反射的引入1.1 什么是反射机制呢?1.2 反射机制的优点与缺点2 Class类2.1 获得Class对象2.2 Classloader中loadClass()方法Class.forName()区别2.3 源码解析2.3.1 ClassLoader.loadClass源码...
  • 前言众所周知,Java目前影响最大的是反序列化漏洞,换一句话说Java安全是从反序列化漏洞开始,但反序列化漏洞又可以基于反射,这次笔者带你走进Java安全的大门。Java反序列化的payload大多与反射机制密切相关,但...
  • 针对工程应用中对静态或低频动态微小角度的高精度测量需求,基于双平面镜多次反射增大光线反射角 的方法构建了一种二维偏转角度测量装置
  • 从安全角度谈Java反射机制--序章

    千次阅读 2020-05-07 17:07:23
    从安全角度谈Java反射机制第一篇,一共三篇由浅入深,一点点剖析Java的反射机制。
  • 阐述了利用非均匀膜系理论设计宽角度多层减反射薄膜的方法,从理论上分析了在宽角度的情况下,偏振光产生透过率不同的原因,选取了Ta2O5和SiO2两种材料作为折射率材料,选取BK7作为基底材料模拟设计了光谱区在600~700 ...
  • 采用LiF和Ge两种材料设计了一种禁带范围覆盖全可见光波段,结构为[A1/B1]m[A2/B2]n的复合结构一维光子晶体反射器,并采用平面波展开法和传输矩阵法...研究结果可为实现可见光波段大角度反射器的制备及应用提供理论支持。
  • 反射角度说JAVA属于半动态语言。反射机制java反射机制:在运行状态下,对任意一个类都能知道这个类的所有的属性和方法;并且对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息以及动态调用对象...
  • 运用新研制的大气多角度偏振辐射计(AMPR)获得航空遥感数据并结合实验室测量数据对常用的三种地表偏振模型进行评估,分析地表偏振反射率的波段响应和角度响应特征。实验发现偏振反射率对波段变化的响应很小,该结论...
  • 从另一个角度理解Java中的反射 主要内容: JVM是如何构建一个实例的 .class文件 类加载器 Class类 反射API JVM是如何构建一个实例的 假设main方法中有以下代码: Person p = new Person(); 会经历以下这个过程: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,580
精华内容 632
关键字:

反射角度