精华内容
下载资源
问答
  • java反射底层原理

    千次阅读 2017-12-27 17:04:25
    反射的Method.invoke前15次是调用navite code用C++实现的,后面使用java实现 原因: Java实现的版本在初始化时需要较多时间,但长久来说性能较好;native版本正好相反,启动时相对较快,但运行时间长了之后速度...

    反射的Method.invoke前15次是调用navite code用C++实现的,后面使用java实现
    原因:

    Java实现的版本在初始化时需要较多时间,但长久来说性能较好;native版本正好相反,启动时相对较快,但运行时间长了之后速度就比不过Java版了。这是HotSpot的优化方式带来的性能特性,同时也是许多虚拟机的共同点:跨越native边界会对优化有阻碍作用,它就像个黑箱一样让虚拟机难以分析也将其内联,于是运行时间长了之后反而是托管版本的代码更快些。
    为了权衡两个版本的性能,Sun的JDK使用了“inflation”的技巧:让Java方法在被反射调用时,开头若干次使用native版,等反射调用次数超过阈值时则生成一个专用的MethodAccessor实现类,生成其中的invoke()方法的字节码,以后对该Java方法的反射调用就会使用Java版。

    参考:
    关于反射调用方法的一个log
    深入分析Java方法反射的实现原理

    自己做的淘宝哦京东优惠券搜索助手,自动回复个人号,欢迎关注体验
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

    展开全文
  • java反射底层原理

    千次阅读 2019-08-18 22:14:15
    Java反射机制是java的这门语言所独有的,这也是面试官喜欢问的知识点之一,我们不能仅仅从会使用反射这个类以及类中方法,来认定自己会这个知识点,我认为这太过于表面,不是我们学习java的正确的方式。 首先我们先...

    Java反射机制是java的这门语言所独有的,这也是面试官喜欢问的知识点之一,我们不能仅仅从会使用反射这个类以及类中方法,来认定自己会这个知识点,我认为这太过于表面,不是我们学习java的正确的方式。

    首先我们先了解反射的相关概念:反射是指java运行状态中,任何类都能知道当前类的属性和方法,任何对象都能调用当前对象的属性和方法。
    我们首先来看一个例子:
    package com.javabase.reflect;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Demo01 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
            Class p1 = Class.forName("com.javabase.reflect.person");
            System.out.println(p1.getName());
            Method m1 = p1.getMethod("test2");
            System.out.println(m1);
            Field[] fields = p1.getFields();
            for (Field f:fields){
                System.out.println(f.getName());
            }
        }
    }
    
    这是个简单的反射的例子,其中我认为反射的最重要的一句代码,也是java发射的核心代码 — Class.forName(“当前类的地址”);,这是该类被加载到java虚拟机的过程。我们可以从forName中的源码可以看出
     public static Class<?> forName(String className)
                    throws ClassNotFoundException {
            Class<?> caller = Reflection.getCallerClass();
            return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
        }
    
    我们可以看出有个类加载的过程

    在这里插入图片描述

    就是将当前类的对象加载到java虚拟机中,得到了类对象,类对象存在java的堆中,所有的类的类对象都被java虚拟机存储在jvm中的堆中,方便java虚拟机对类对象的管理。
    可以通过上述的例子来画出java虚拟机中运行的图。

    在这里插入图片描述

    这就是我的个人理解,如有错误,还望各位指教。
    展开全文
  • 最容易理解的反射机制的底层原理

    千次阅读 2020-05-21 15:36:14
    看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依据自己的理解去阐述什么是Java的反射机制,反射用在什么地方,以及怎么来使用? 开篇前,我们还是要了解一下,什么是Java的...

    看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依据自己的理解去阐述什么是Java的反射机制,反射用在什么地方,以及怎么来使用?

    开篇前,我们还是要了解一下,什么是Java的反射机制:

    “程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl、Python(看过我写的Python3学习系列的博文,不止一次突出Python动态语言的特点)、Ruby是动态语言,C++、Java、C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制——Reflection(反射),用在Java身上指的是可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体(newInstance)或对其fields设值,或唤起(invoke)其methods方法。

    注意 方法的声明和定义不是一回事,
    声明:public string Method(string parm1,int param2,…)
    定义:public string Method(string parm1,int param2,…)
              {
                    // do something
              }

    反射用在什么地方?

    由于,我们还不清楚反射究竟是什么玩意,怎么用,是不是我们平时写代码的时候会用得上? 这些,都不知道的话,我们也没法定论,这个Java反射机制,用在什么地方比较和合适(注意,一项技术的诞生,一定是为了方便另一项技术的使用,否则会失去本身存在的意义!)

    因此,我们先来说一下,反射怎么用?

    一、反射的应用

    我们可能听过,Java编写的程序,一次编译,到处运行。这也是Java程序为什么是无关平台的所在,原因在于,java的源代码会被编译成.class文件字节码,只要装有Java虚拟机JVM的地方(Java提供了各种不同平台上的虚拟机制,第一步由Java IDE进行源代码编译,得到相应类的字节码.class文件,第二步,Java字节码由JVM执行解释给目标计算机,第三步,目标计算机将结果呈现给我们计算机用户;因此,Java并不是编译机制,而是解释机制),.class文件畅通无阻。

    Java的反射机制,操作的就是这个.class文件,首先加载相应类的字节码(运行eclipse的时候,.class文件的字节码会加载到内存中),随后解剖(反射 reflect)出字节码中的构造函数、方法以及变量(字段),或者说是取出,我们先来定义一个类Animal,里面定义一些构造函数,方法,以及变量:

    Animal.java:

    package com.appleyk.reflect;

    public class Animal {

    public String name ="Dog";
    private int   age  =30 ;
    
    //默认无参构造函数
    public Animal(){
    	System.out.println("Animal");
    }
    
    //带参数的构造函数 
    public Animal(String name , int age){
    	System.out.println(name+","+age);
    }
    
    //公开 方法  返回类型和参数均有
    public String sayName(String name){
    	return "Hello,"+name;
    }
    

    }

    我们再定义一个测试类:

    ReflectTest.java

    package com.appleyk.test;

    public class ReflectTest {

    public static void main(String args[]) throws Exception{
    	
    	//do something 
    }
    

    }

    我们运行一下我们的项目,会发现如下:

    对应内存中就是:

    我们借助javap命令查看一下,这个Animal.class里面的内容是什么:

    F:\Java\ReflectClass\bin\com\appleyk\reflect>javap -c Animal.class
    Compiled from “Animal.java”
    public class com.appleyk.reflect.Animal {
    public java.lang.String name;

    public com.appleyk.reflect.Animal();
    Code:
    0: aload_0
    1: invokespecial #12 // Method java/lang/Object."":
    ()V
    4: aload_0
    5: ldc #14 // String Dog
    7: putfield #16 // Field name:Ljava/lang/String;
    10: aload_0
    11: bipush 30
    13: putfield #18 // Field age:I
    16: getstatic #20 // Field java/lang/System.out:Ljava/
    io/PrintStream;
    19: ldc #26 // String Animal
    21: invokevirtual #28 // Method java/io/PrintStream.printl
    n:(Ljava/lang/String;)V
    24: return

    public com.appleyk.reflect.Animal(java.lang.String, int);
    Code:
    0: aload_0
    1: invokespecial #12 // Method java/lang/Object."":
    ()V
    4: aload_0
    5: ldc #14 // String Dog
    7: putfield #16 // Field name:Ljava/lang/String;
    10: aload_0
    11: bipush 30
    13: putfield #18 // Field age:I
    16: getstatic #20 // Field java/lang/System.out:Ljava/
    io/PrintStream;
    19: new #39 // class java/lang/StringBuilder
    22: dup
    23: aload_1
    24: invokestatic #41 // Method java/lang/String.valueOf:(
    Ljava/lang/Object;)Ljava/lang/String;
    27: invokespecial #47 // Method java/lang/StringBuilder."<
    init>":(Ljava/lang/String;)V
    30: ldc #49 // String ,
    32: invokevirtual #51 // Method java/lang/StringBuilder.ap
    pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    35: iload_2
    36: invokevirtual #55 // Method java/lang/StringBuilder.ap
    pend:(I)Ljava/lang/StringBuilder;
    39: invokevirtual #58 // Method java/lang/StringBuilder.to
    String:()Ljava/lang/String;
    42: invokevirtual #28 // Method java/io/PrintStream.printl
    n:(Ljava/lang/String;)V
    45: return

    public java.lang.String sayName(java.lang.String);
    Code:
    0: new #39 // class java/lang/StringBuilder
    3: dup
    4: ldc #64 // String Hello,
    6: invokespecial #47 // Method java/lang/StringBuilder."<
    init>":(Ljava/lang/String;)V
    9: aload_1
    10: invokevirtual #51 // Method java/lang/StringBuilder.ap
    pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    13: invokevirtual #58 // Method java/lang/StringBuilder.to
    String:()Ljava/lang/String;
    16: areturn
    }

    我们发现,字节码里面包含了类Animal的构造函数、变量以及方法,但注意,全都是public类型的,我们的定义的类的私有变量 private int   age  =30 哪去了?当然,既然是类的私有部分,肯定不会暴露在外面的,但是不阻碍我们通过反射获得字节码中的私有成员(本篇只举例说明私有变量(字段field),其他私有类成员同理)。

    我们的类Animal在Anima.java中定义,但在Animal.class文件中,我们的Animal类阐述如下:

    下面,我们来写一段demo,来演示一下,如何使用反射机制,将.class文件中的类加载出来,并解剖出字节码中对应类的相关内容(构造函数、属性、方法):

    看代码前,我们学两个小技巧:

    (1)获得类的完全限定名:

    copy以后,直接paste

    (2)自动生成返回值对象

    ReflectTest.java:

    package com.appleyk.test;

    import java.lang.reflect.Constructor;

    import com.appleyk.reflect.Animal;

    public class ReflectTest {

    public static void main(String args[]) throws Exception{
    	
    	//do something 
    	//1、加载类 ,指定类的完全限定名:包名+类名
    	 Class c1 = Class.forName("com.appleyk.reflect.Animal");
    	 System.out.println(c1);//打印c1,发现值和字节码中的类的名称一样
    	
    	 //2、解刨(反射)类c1的公开构造函数,且参数为null 
    	 Constructor ctor1= c1.getConstructor();
    	 
    	//3、构造函数的用途,就是创建类的对象(实例)的
    	//除了私有构造函数外(单列模式,禁止通过构造函数创建类的实例,保证一个类只有一个实例)
    	//ctor1.newInstance()默认生成一个Object对象,我们需要转化成我们要的Animal类对象
    	// Object a1 = ctor1.newInstance();
    	 Animal a1 = (Animal)ctor1.newInstance(); 
    	
    	//4、证明一下a1确实是Animal的实例,我们通过访问类中的变量来证明
    	 System.out.println(a1.name);
    }
    

    }

    我们看下,上述demo 的执行结果:

    我们接着走,获得类中的变量(字段)和方法,两种方式,一个是getXXX,一个是getDeclaredXXX,二者是有区别的,下面demo注释的很详细,并且,我们使用反射出的字段和方法,去获取相应实例的字段值和唤起方法(相当于执行某实例的方法),我们看下完整版demo:
     
    加强版的 ReflectTest.java

    package com.appleyk.test;

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;

    import com.appleyk.reflect.Animal;

    public class ReflectTest {

    public static void main(String args[]) throws Exception {
    
    	// do something
    
    	System.out.println("A(无参构造函数)--加载类、反射类的构造函数、利用构造函数new一个Animal实例instance--");
    
    	// 1、加载类 ,指定类的完全限定名:包名+类名
    	Class c1 = Class.forName("com.appleyk.reflect.Animal");
    	System.out.println(c1);// 打印c1,发现值和字节码中的类的名称一样
    
    	// 2.a、解刨(反射)类c1的公开构造函数,且参数为null
    	Constructor ctor1 = c1.getConstructor();
    
    	// 3、构造函数的用途,就是创建类的对象(实例)的
    	// 除了私有构造函数外(单列模式,禁止通过构造函数创建类的实例,保证一个类只有一个实例)
    	// ctor1.newInstance()默认生成一个Object对象,我们需要转化成我们要的Animal类对象
    	// Object a1 = ctor1.newInstance();
    	Animal a1 = (Animal) ctor1.newInstance();
    
    	// 4、证明一下a1确实是Animal的实例,我们通过访问类中的变量来证明
    	System.out.println(a1.name);
    
    	System.out.println("A(有参构造函数)--加载类、反射类的构造函数、利用构造函数new一个Animal实例instance--");
    	// 2.b、 解刨(反射)类c1的公开构造函数,参数为string和int
    	Constructor ctor2 = c1.getConstructor(String.class, int.class);
    	Animal a2 = (Animal) ctor2.newInstance("Cat", 20);
    
    	System.out.println("B--获得本类中的所有的字段----------------------------");
    
    	// 5、获得类中的所有的字段 包括public、private和protected,不包括父类中申明的字段
    	Field[] fields = c1.getDeclaredFields();
    	for (Field field : fields) {
    		System.out.println(field);
    
    	}
    
    	System.out.println("C--获得本类中的所有公有的字段,并获得指定对象的字段值-----");
    
    	// 6、获得类中的所有的公有字段
    	fields = c1.getFields();
    	for (Field field : fields) {
    		System.out.println(field + ", 字段值 = " + field.get(a1));
    		// 注意:私有变量值,无法通过field.get(a1)进行获取值
    		// 通过反射类中的字段name,修改name的值(注意,原值在类中name="Dog")
    		// 如果,字段名称等于"name",且字段类型为String,我们就修改字段的值,也就是类中变量name的值
    		if (field.getName() == "name" && field.getType().equals(String.class)) {
    			String name_new = (String) field.get(a1);// 记得转换一下类型
    			name_new = "哈士奇";// 重新给name赋值
    			field.set(a1, name_new);// 设置当前实例a1的name值,使修改后的值生效
    		}
    	}
    
    	System.out.println("利用反射出的字段,修改字段值,修改后的name = " + a1.name);
    	System.out.println("D--获取本类中的所有的方法--------------------");
    
    	// 7、获取本类中所有的方法 包括public、private和protected,不包括父类中申明的方法
    	Method[] methods = c1.getDeclaredMethods();
    	for (Method m : methods) {
    		System.out.println(m);// 我们在类Animal中只定义了一个public方法,sayName
    	}
    
    	System.out.println("E--获取本类中的所有的公有方法,包括父类中和实现接口中的所有public方法-----------");
    
    	// 8、获取类中所有公有方法,包括父类中的和实现接口中的所有public 方法
    	methods = c1.getMethods();
    	for (Method m : methods) {
    		System.out.println(m);// 我们在类Animal中只定义了一个public方法,sayName
    	}
    
    	System.out.println("F--根据方法名称和参数类型获取指定方法,并唤起方法:指定所属对象a1,并给对应参数赋值-----------");
    
    	// 9、唤起Method方法(执行) getMethod:第一个参数是方法名,后面跟方法参数的类
    	Method sayName = c1.getMethod("sayName", String.class);
    	System.out.println(sayName.invoke(a1, "Tom"));
    
    }
    

    }

    我们看下对应的执行结果:

    如果,你对上述执行的结果,一次性接收不了的话,建议将上述测试demo自己亲自敲一遍,先别急着一次性敲完,一点点来,按照序号来,你会发现,反射的机制,无非就是先加载对应字节码中的类,然后,根据加载类的信息,一点点的去解剖其中的内容,不管你是public的还是private的,亦或是本类的还是来自原继承关系或者实现接口中的方法,我们java的反射技术 reflect,均可以将其从字节码中拉回到现实,不仅可以得到字段的名字,我们还可以获得字段的值和修改字段的值,不仅可以得到方法的申明我们还可以拿到方法的定义和唤起方法(执行方法),当然,你会有一个这样的疑惑?
     
    为什么new一个对象那么简单,非要用反射技术中的newInstance?
    为什么,我可以直接对象a1. 变量访问变量,却非要用反射那么费劲的获得name字段呢?
    为什么,我几行代码就能搞定的事情,非要用反射呢?

    回到最开始我们讲的地方:

    ok,解密答案之前,我们先来思考一个问题?
     
    假设我们定义了很多类,有Animal、Person、Car… ,如果我想要一个Animal实例,那我就new Animal(),如果另一个人想要一个Person实例,那么他需要new Person(),当然,另一个说,我只要一个Car实例,于是它要new Car()…这样一来就导致,每个用户new的对象需求不相同,因此他们只能修改源代码,并重新编译才能生效。这种将new的对象写死在代码里的方法非常不灵活,因此,为了避免这种情况的方法,Java提供了反射机制,典型的应用如下:

    我们知道Spring的IOC吧,即“控制反转”(通过第三方配置文件实现对 对象的控制)。简单说是将我们设计好的对象交给容器控制,而不是直接交给程序内部进行对象的控制。
     
    比如,在Spring中,我们经常看到:

    针对上述的配置,我们Spring是怎么帮助我们实例化对象,并放到容器中去了呢? 没错,就是通过反射!!!!
     
    我们看下,下面的伪代码实现过程:

    //解析<bean …/>元素的id属性得到该字符串值为"sqlSessionFactory"
    String idStr = “sqlSessionFactory”;
    //解析<bean …/>元素的class属性得到该字符串值为"org.mybatis.spring.SqlSessionFactoryBean"
    String classStr = “org.mybatis.spring.SqlSessionFactoryBean”;
    //利用反射知识,通过classStr获取Class类对象
    Class cls = Class.forName(classStr);
    //实例化对象
    Object obj = cls.newInstance();
    //container表示Spring容器
    container.put(idStr, obj);

        //当一个类里面需要用另一类的对象时,我们继续下面的操作
        
        //解析<property .../>元素的name属性得到该字符串值为“dataSource”  
        String nameStr = "dataSource";  
        //解析<property .../>元素的ref属性得到该字符串值为“dataSource”  
        String refStr = "dataSource";  
        //生成将要调用setter方法名  
        String setterName = "set" + nameStr.substring(0, 1).toUpperCase()  
                + nameStr.substring(1);  
        //获取spring容器中名为refStr的Bean,该Bean将会作为传入参数  
        Object paramBean = container.get(refStr);  
        //获取setter方法的Method类,此处的cls是刚才反射代码得到的Class对象  
        Method setter = cls.getMethod(setterName, paramBean.getClass());  
        //调用invoke()方法,此处的obj是刚才反射代码得到的Object对象  
        setter.invoke(obj, paramBean);  
    

    是不是很熟悉,虽然是伪代码,但是和我们本篇讲的反射机制的使用是相同的,现在知道我们的反射机制用在哪了吧,没错就是我们经常提到的Java web框架中,里面就用到了反射机制,只要在代码或配置文件中看到类的完全限定名(包名+类名),其底层原理基本上使用的就是Java的反射机制。
     
     
    因此,如果你不做框架的话,基本上是用不到反射机制的,我们大多时候是使用框架的一方,而反射机制都已经在底层实现过了,因此,我们不必担心,我们会写那么复杂的代码。但是,我们必须要理解这种机制的存在!
    ————————————————
    版权声明:本文为CSDN博主「appleyk」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Appleyk/article/details/77879073

    展开全文
  • Java反射篇详细~讲解底层原理

    千次阅读 2019-02-18 15:53:40
    反射(Java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class) #####Class类代表java类,它的各个实例对象分别对应什么? 对应各个类在内存中的字节码,例如Person类的字节码,ArrayList类的字节码...

    #反射(Java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class)

    #Class类代表java类,它的各个实例对象分别对应什么?

    对应各个类在内存中的字节码,例如Person类的字节码,ArrayList类的字节码等等
    一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同类的字节码是不同的,这一个个空间分别用一个对象来表示,这些对象具备相同的类型。

    ##三种方式得到class类型

    1. 类名.class,例如System.class;
    2. 对象.getClass(),例如new Date.getClass();
    3. class.forName(“包名+类名”),例如Class.forName(“java.util.Date”);

    ###九个预定义的class实例对象(除了八个基本类型还有一个void也有class类型)
    Class.isPrimitive方法查看程序中出现的类型都有各自的Class实例对象,到底是什么类型
    int.class == Integer.Type(true)
    数组类型的class对象实例通过isArray()查看
    ##反射概念理解:
    反射就是把java类中的各种成分映射成相应的java类。

    例如一个java类中用一个class类的对象来表示。一个类中的组成部分:成员变量、方法、构造方法、包等等信息也用一个个java类来表示,就像一个汽车是一个类,汽车中的发动机,变速箱等等也是一个个类。表示java类的class类显然要提供一系列方法,来获取其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
    构造方法的反射应用(Constructor)
    Constructor类代表某个类中的一个构造方法
    得到某个类所有的构造方法:

    例子:Constructor[] constructor = 
    Class.forName("java.lang.String").getConstructors();
    

    得到某一个构造方法:
    例子: Constructor constructor =
    Class.forName(“java.lang.String”).getConstructor(StringBuffer.class)
    创建实例对象:

    通常方式:String str = new String(new StringBuffer("abc"))
    反射方式:String str = constructor.newlnstance(new StringBuffer("abc"));
    

    反射获取对象实例的一般方式 class–>Constructor–>newlnstance
    调用获得的方法时要用上面相同类型的实例对象
    ##Class.newlnstance()方法:(反射获取对象实例的便捷方式class–>newlnstance)
    例子:String str = Class.forName(“java.lang.String”).newlnstance();

    该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象

    ##Field类代表某个类中的一个成员变量
    案例 person类
    public int x;
    private int y;
    getter and setter

    ##通过反射获取属性值

    Person p =new Person(1,2);
    Field fieldx = p.getClass().getField("y");
    //field x 的值是多少? 是1?,错!fieldx不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
    System.out.println(fieldx.get(p));
    //获取y属性的时候由于是私有的用暴力反射获取
    Field fieldy = p.getClass().getDeclaredField("x");
    fieldy.setAccessiable(true);
    System.out.println(field.get(p));
    

    ##Method代表类中的一个成员方法

    例子:Method methodCharAt = Class.forName("java.lang.String").getMethod("charAt",int.class);
    //getMethod后面一个参数是参数类型的可变长参数类型str.charAt(1)参数是int所以是int.class
    通用方式:System.out.println(str.charAt(1));
    反射方式:System.out.println(methodCharAt.invoke(str,1));
    //method的invoke是mentod的方法,调用invoke的时候才代表charAt方法执行
    

    如果传递给Method对象的invoke()方法的第一个参数为null,这有什么样的意义呢?说明该method传递对象对应的是一个静态方法

    ##反射的应用:

    //修改对象String属性b换成a
    public static void changeStringVlaue(Obeject obj){
    Field field = obj.getClass().getFileds();
    for(field.getType == String.class){
    	String oldVlaue = (String) field.get(obj);
    	String newValue = oldVlaue.replace('b','a');
    	field.set(obj,newValue);
    	}
    }
    

    ##2019/2/18数组的反射(与Object的关系)

    基本数据类型没有 父类。
    基本数据类型的包装类的父类是 java.lang.Number
    Number 的父类也是Object
    那么我们也可以说,Object 也是基本数据类型的包装类的父类 。
    数组的父类也是Object
    String 的父类是Object。

    int[] a1 = new int[]{1,2,3};
    int[] a2 = new int[2];
    int[][] a3 = new int[1][2];
    String[] a4 = new String[]{"111","222","333"};
    Object obj1 = a1;
    Object obj4 = a4;
    //Object[] obj11 = a1;//错误,因为a1一维数组可以看做是一个对象,但是不能看成是一个对象数组
    Object[] obj3 = a3;//二维数组可以看做一维数组里面包含一个数组,而一维数组可以看做一个对象,所有二维可以看做是一个对象数组
    Object[] obj44= a4;//字符串可以看做对象,所有字符串数组就可以看做是对象数组
    
    操作数组的工具类Arrays.asList(数组)可以把数组转换成List
    System.out.println(Arrays.asList(a1));//打印[[数组的哈希码地址]
    
    System.out.println(Arrays.asList(a4));//打印集合元素
    

    #反射的作用–>实现框架的功能

    框架与框架要解决的核心问题:

    把框架看着是房子的话,我把房子卖给客户住(这个房子只是一个空的没有配带家具和门窗),有用户自己安装家具和门窗,房子看做框架,用户需要使用我提供的框架,把门窗和家具插入我的框架中。框架和工具类存在区别,工具类被用户的类调用,而框架则是调用用户提供的类。
    框架要解决的核心问题:
    问:我在写(房子)框架的时候,客户这个人可能在干其他的,还不会写程序,我写的框架程序怎么能掉用你以后写的(门窗)类呢?
    **答:因为在写程序时无法知道要被调用的类名,所有无法直接new某个类的实例对象,所有需要用到反射来实现。 **

    通过反射写一个小框架的应用:

    在ide工具中创建一个配置文件 config.properties(内容为:className =java.util.HashSet )
    然后通过字节流输入流(读进来)读取配置文件 InputStream input = new FileInputStream(配置文件路径);
    
    创建配置文件 Properties pro = new Properties();
    通配置文件加载输入流读取的内容 pro.load(input);
    最后关流 input.close();
    获取配置文件的key String className = pro.getProperty("calssName"); 
    通过反射获取配置文件value的实例对象 Collections collection = (Collections) class.forName("className").newInstance();
    创建几个对象(该对象重新生成了hashcode()和equals()方法) 
    			Person p1 = new Person(10,"小明");
    			Person p2 = new Person(12,"小白");
    			Person p3 = new Person(12,"小白");
    	collection.add(p1);collection.add(p2);collection.add(p3);
    
    System.out.println(collection.size());//长度打印出来了为2,反射成功!!!
    

    ##使用类加载器加载这些文件

    适用场景:资源文件和类文件在不在同一目录都可以
    注意:getResourceAsStream里的参数要写资源文件的全限定路径,
    包名+文件名且开头千万不要写"/"

    使用方法:

    InputStream ips = 类名.class.getClassLoader().getResourceAsStream("配置文件的路径“);
    
    例如:InputStream ips = TestReflect2.class.getClassLoader().getResourceAsStream("itcast/cn/Reflect/config.properties");
    注意:ClassLoader加载配置文件时,它是在classpath 的根路径下搜索,所以在填写配置文件的路径时要特别注意。bin是classpath 根路径,在配置文件钱要加上完整的包名。
    
    展开全文
  • IOC容器底层实现原理利用反射

    多人点赞 2021-07-09 21:04:30
    掌握反射是每个JAVA程序员必不可缺少的技能 基本上所有的框架底层实现原理都有反射如:不会spring框架都不好意思说自己是搞JAVA的 spring框架; spring框架有三大核心特性: IOC(控制反转) Dl(依赖注入) AOP(面向切...
  • JAVA反射PPT,,简单介绍反射的实现和机制,
  • java反射原理详解

    2017-08-10 11:32:26
    java反射原理详解
  • 反射基本原理与实现

    千次阅读 2020-10-04 18:27:08
    一,反射是什么 1 JAVA反射机制是在运行状态中 对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性; 这种动态获取的信息以及动态调用对象的方法的功能称为...
  • Go反射的实现和 interface 和 unsafe.Pointer 密切相关。如果对golang的 interface 底层实现还没有理解,可以去看我之前的文章: Go语言interface底层实现 , unsafe.Pointer 会在后续的文章中做介绍。 (本文目前...
  • 2.反射底层原理3.反射在spring IOC容器中的使用3.反射的常用API 1.反射是什么? java反射机制指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性...
  • java反射原理-重要

    万次阅读 多人点赞 2018-11-20 23:00:19
    一,反射是什么(反射是框架设计的灵魂) 1,JAVA反射机制是在运行状态中 对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性; 这种动态获取的信息以及...
  • Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射...
  • Android -从浅到懂使用反射机制

    千次阅读 2020-12-09 09:17:32
    JAVA反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法; 对于任何一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。 ...
  • java反射原理反射机制原理,以及java反射机制实现实例!希望能给大家一点帮助!
  • java反射原理及作用

    2009-03-06 05:03:48
    j2me 是电子数 希望大家喜欢 我都库了,怎么传不上去啊
  • Android反射机制实现与原理

    千次阅读 2016-09-12 14:24:31
    本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一、反射的概念及在Java中的类反射  反射主要是指程序可以访问、检测和修改它本身状态或行为的一种...
  • java反射机制和动态代理的原理,熟悉反射机制和动态代理
  • C#反射机制

    千次阅读 2019-02-28 14:01:43
    四十五:反射的实现原理? 审查元数据并收集关于它的类型信息的能力。实现原理:在运行时根据程序集及其中的类型得到元数据。下面是实现步骤: 1. 导入using System.Reflection; 2. Assembly.Load(“程序集”)...
  • Java方法反射的实现原理

    万次阅读 2018-09-12 15:29:53
    前段时间看了笨神的 从一起GC血案谈到反射原理一本,就把Java方法的反射机制实现撸了一遍。 方法反射实例 public class ReflectCase { public static void main(String[] args) throws Exception { Pro...
  • JAVA反射原理

    2019-03-01 16:29:39
    JAVA反射原理1 JAVA反射原理2 JAVA反射原理3
  • java底层原理

    2020-11-02 22:51:12
    有人反射,克隆,反序列化我的时候,我会被加载,连接,初始化。 一个类在每次被使用前,都会先检查是否被加载,连接,初始化过: 如果已经被加载,连接,初始化过,则直接使用。 如果仍未被加载,连接,初始化过,...
  • IOC容器底层原理

    2021-04-18 23:55:56
    一、IOC底层实现原理 框架 = 解析 + 反射 + 工厂 XML解析 XML配置文件,配置创建的对象 工厂模式 原始的方式是在UserService中new一个UserDAO的对象,然后调用对象中的方法,这样使得两个类的耦合度很高。 而工厂...
  • Spring ioc的底层原理

    2019-10-20 15:35:04
    一般来说,我们在写项目的时候,如果需要更改一...我们可以通过这张图来了解ioc的底层实现原理, 第一步,在xml文件中配置对象类的信息,其中包括id 和 class 第二步,我们创建一个返回值为service的工厂类,根据反...
  • Swift之深入解析反射Mirror的底层原理

    万次阅读 2021-06-12 13:23:43
    一、Mirror 的底层分析 ① 反射 API 反射 API 由两部分实现: 一部分是通过 Swift 实现,即 ReflectionMirror.swift; 一部分是通过 C++ 实现,即 ReflectionMirror.mm; 两者之间是通过暴露给 Swift 的 ...
  • 方法反射实例  public class ReflectCase {  public static void main(String[] args) throws Exception {  Proxy target = new Proxy();  Method method = Proxy.class.
  • 《Go语言底层原理剖析》这本书便可以帮助读者解决以上问题。 本书语言通俗易懂,书中有系统权威的知识解构、精美的示意图,并对照源码和参考文献字斟句酌,在一线大规模系统中提炼出设计哲学与避坑方法,对于编译时...
  • Tomcat底层原理

    千次阅读 2019-11-06 11:02:21
    原理上是可以的,但是就像我们开发业务一样,我们不会将真正实现业务的方法直接暴露给其他人调用,而会提供一个接口,操作系统也一样,这个接口就是Socket。 所以Tomcat是通过Socket从操作系统获取数据的,拿到数据...
  • Spring底层原理

    千次阅读 2019-04-02 13:53:30
    Spring IOC / DI底层实现原理 问题说明:Spring是如何通过配置文件,就完成了对象的创建和属性的赋值? 答案: 使用工厂设计模式 + 配置文件 + 反射 描述: 使用工厂设计模式,在工厂中,根据配置...
  • 动态代理的底层原理

    千次阅读 2018-04-06 17:02:37
    动态代理的底层原理 1、静态代理 2、动态代理的使用 2.1、基于接口的动态代理(使用的JDK自带的API) 2.2、基于类继承关系的动态代理(使用的cglib.jar自带的API) 2.3、提个问题? 3、代理出的类到底是什么? 3.1...
  • java多态的底层原理

    千次阅读 2019-05-09 20:40:16
    虚拟机运行角度解释多态实现原理 动态绑定、方法表 将一个方法调用同一个方法主体关联起来被称作绑定,JAVA中分为前期绑定和后期绑定(动态绑定) 在程序执行之前进行绑定(由编译器和连接程序实现)叫做前期绑定 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,005
精华内容 20,002
关键字:

反射的底层原理