反射_反射机制 - CSDN
反射 订阅
反射是一种计算机处理方式。有程序可以访问、检测和修改它本身状态或行为的这种能力。能提供封装程序集、类型的对象。(程序集包含模块,而模块包含类型,类型又包含成员。) 展开全文
反射是一种计算机处理方式。有程序可以访问、检测和修改它本身状态或行为的这种能力。能提供封装程序集、类型的对象。(程序集包含模块,而模块包含类型,类型又包含成员。)
信息
性    质
计算机术语
应用领域
软件工程
外文名
reflection
中文名
反射
基本释义
提供封装程序集、类型的对象
反射用途
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。1.使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。2.使用 Module 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。3.使用 ConstructorInfo 了解如下的类似信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。4.使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。5.使用 MethodInfo 来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。6.使用 FieldInfo 来了解如下的类似信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。7.使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。8.使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。9.使用 ParameterInfo 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
收起全文
精华内容
参与话题
  • JAVA中的反射机制

    万次阅读 多人点赞 2014-01-08 22:31:58
    反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!  一,先看一下反射的概念:   主要是指程序可以访问,检测和...

               反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!


               一,先看一下反射的概念:

                  主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

                 反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!

                 看概念很晕的,继续往下看。

     

          二,反射机制的作用:

                  1,反编译:.class-->.java

                  2,通过反射机制访问java对象的属性,方法,构造方法等;

                 这样好像更容易理解一些,下边我们具体看怎么实现这些功能。


          三,在这里先看一下sun为我们提供了那些反射机制中的类:

    java.lang.Class;                

    java.lang.reflect.Constructor; java.lang.reflect.Field;        

    java.lang.reflect.Method;

    java.lang.reflect.Modifier;


                很多反射中的方法,属性等操作我们可以从这四个类中查询。还是哪句话要学着不断的查询API,那才是我们最好的老师。


             四,具体功能实现:

                    1,反射机制获取类有三种方法,我们来获取Employee类型

    //第一种方式:
    Classc1 = Class.forName("Employee");
    //第二种方式:
    //java中每个类型都有class 属性.
    Classc2 = Employee.class;
     
    //第三种方式:
    //java语言中任何一个java对象都有getClass 方法
    Employeee = new Employee();
    Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)

     

        2,创建对象:获取类以后我们来创建它的对象,利用newInstance

                Class c =Class.forName("Employee");
     
                //创建此Class 对象所表示的类的一个新实例
                Objecto = c.newInstance(); //调用了Employee的无参数构造方法.


        3,获取属性:分为所有的属性和指定的属性:

          a,先看获取所有的属性的写法:

    //获取整个类
    			Class c = Class.forName("java.lang.Integer");
    		      //获取所有的属性?
    			Field[] fs = c.getDeclaredFields();
    	 
    	               //定义可变长的字符串,用来存储属性
    			StringBuffer sb = new StringBuffer();
    	        //通过追加的方法,将每个属性拼接到此字符串中
    			//最外边的public定义
    			sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");
    	        //里边的每一个属性
    			for(Field field:fs){
    				sb.append("\t");//空格
    				sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
    				sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
    				sb.append(field.getName()+";\n");//属性的名字+回车
    			}
    	
    			sb.append("}");
    	
    			System.out.println(sb);
    

           b,获取特定的属性,对比着传统的方法来学习:


    public static void main(String[] args) throws Exception{
    			
    	//以前的方式:
    	/*
    	User u = new User();
    	u.age = 12; //set
    	System.out.println(u.age); //get
    	*/
    			
    	//获取类
    	Class c = Class.forName("User");
    	//获取id属性
    	Field idF = c.getDeclaredField("id");
    	//实例化这个类赋给o
    	Object o = c.newInstance();
    	//打破封装
    	idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
    	//给o对象的id属性赋值"110"
    	idF.set(o, "110"); //set
    	//get
    	System.out.println(idF.get(o));
    }
    

     4,获取方法,和构造方法,不再详细描述,只来看一下关键字:

    方法关键字

    含义

    getDeclaredMethods()

    获取所有的方法

    getReturnType()

    获得方法的放回类型

    getParameterTypes()

    获得方法的传入参数类型

    getDeclaredMethod("方法名",参数类型.class,……)

    获得特定的方法

     

     

    构造方法关键字

    含义

    getDeclaredConstructors()

    获取所有的构造方法

    getDeclaredConstructor(参数类型.class,……)

    获取特定的构造方法

     

     

    父类和父接口

    含义

    getSuperclass()

    获取某类的父类

    getInterfaces()

    获取某类实现的接口

      

             这样我们就可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。

     

      五,反射加配置文件,使我们的程序更加灵活:

                 在设计模式学习当中,学习抽象工厂的时候就用到了反射来更加方便的读取数据库链接字符串等,当时不是太理解,就照着抄了。看一下.NET中的反射+配置文件的使用:

                 当时用的配置文件是app.config文件,内容是XML格式的,里边填写链接数据库的内容:

              <configuration>
    			<appSettings>
    				<add     key=""  value=""/>
    			</appSettings>
                </configuration>
    

     反射的写法:   

      assembly.load("当前程序集的名称").CreateInstance("当前命名空间名称".要实例化的类名);

     

              这样的好处是很容易的方便我们变换数据库,例如我们将系统的数据库从SQL Server升级到Oracle,那么我们写两份D层,在配置文件的内容改一下,或者加条件选择一下即可,带来了很大的方便。

                

             当然了,JAVA中其实也是一样,只不过这里的配置文件为.properties,称作属性文件。通过反射读取里边的内容。这样代码是固定的,但是配置文件的内容我们可以改,这样使我们的代码灵活了很多!


        综上为,JAVA反射的再次学习,灵活的运用它,能够使我们的代码更加灵活,但是它也有它的缺点,就是运用它会使我们的软件的性能降低,复杂度增加,所以还要我们慎重的使用它。

    展开全文
  • 什么是反射

    千次阅读 2019-04-27 11:30:18
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。...

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

    Class类

    这个类用于操纵(反向解析)一个类的属性,方法,构造器等。

    Person: name,age,address(Class只要知道你这个Person类,那么它便可知道你所有的属性,不止属性,甚至方法上的注解等等,都会知道。)

    范例:获取一个Class对象

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    public class Test01 {
        public static void main(String[] args) throws ClassNotFoundException {
            String a = "java.lang.String";
    //        String a = "java.lang.HashMap";
    
            // 根据一类的全名字符串来获得一个类的类对象
            Class<?> clazz = Class.forName(a);
            // 获得传递过来的类的所有方法
            Method[] methods = clazz.getDeclaredMethods();
    //        String s = Arrays.toString(methods);
            for (Method m: methods) {
                System.out.println(m);
            }
            System.out.println("------------------------------------------");
            // 获得类的所有属性
            Field[] declaredFields = clazz.getDeclaredFields();
            for(Field d : declaredFields) {
                System.out.println(d);
            }
            System.out.println("-------------------------------------");
            // 获得类的所有构造器
            Constructor<?>[] constructors = clazz.getDeclaredConstructors();
            for (Constructor c : constructors) {
                System.out.println(c);
            }
        }
    }

     

    展开全文
  • 什么是反射反射可以做些什么

    千次阅读 2018-07-09 18:52:00
    阅读目录 什么是反射反射能干嘛?获取类型的相关信息获取类型本身信息(命名空间名、全名、是否是抽象、是否是类、、...获取类型成员信息(通过Tyep中的方法GetMembers)动态调用方法调用方式一(使用InvokeMember...

    什么是反射,反射能干嘛?

    反射是:指程序可以访问、检测和修改它本身状态或行为的一种能力

    反射是一种能力,所以给的定义就是说明了它能干嘛。

    我们平时用反射主要做:

    • 获取类型的相关信息
    • 动态调用方法
    • 动态构造对象
    • 从程序集中获得类型

    获取类型的相关信息

    反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息,如:方法、字段、属性、事件...等等。

    我们获取已加载程序集中类型的Type对象的几种方法:(以StringBuilder 类型为例)

    1. 直接使用typeof操作符 Type T1 = typeof(StringBuilder); 
    2. 通过类型实例 Type T2 = new StringBuilder().GetType(); 
    3. 通过Type类的静态方法 Type T3 = Type.GetType("System.IO.Stream"); 

    不管使用那种,我们最终得到的结果都是一样的。

    那么我们通过Type又能得到些什么信息呢?

    获取类型本身信息(命名空间名、全名、是否是抽象、是否是类、、、等等

    复制代码
    var T1 = typeof(StringBuilder);                      
    Console.WriteLine("命名空间名称:" + T1.Namespace);
    Console.WriteLine("直接基类型:" + T1.BaseType);
    Console.WriteLine("全名:" + T1.FullName);
    Console.WriteLine("是抽象类型:" + T1.IsAbstract);
    Console.WriteLine("是类:" + T1.IsClass);
    //.....等等
    复制代码

    获取类型成员信息(通过Tyep中的方法GetMembers)

    复制代码
    Type T1 = typeof(TClass);
    var Mets = T1.GetMembers();//获取Type对象的所有公有成员           
    foreach (var m in Mets)
    {
        Console.WriteLine("" + m.MemberType.ToString()+ "】:" + m.Name);
        // m.MemberType 是成员类型
    }
    复制代码

    MemberType所能包含的成员类型有哪些呢?如:(可以自己可以F12进去看看)

    注意:其中MemberInfo的属性DeclaringType返回的是这个属性定义的类型,而ReflectedType返回的是获取这个属性的对象类型。

    如:

    复制代码
    Type T2 = typeof(TClass);
    var Mets = T2.GetMembers();//获取所有公共成员(返回值是MemberInfo类型集合)
    foreach (var m in Mets)
    {
        if (m.Name=="Equals")
        {
            Console.WriteLine("" + m.MemberType.ToString() + "】:" + m.Name);
            // m.MemberType 是成员类型
    
            // m.DeclaringType;//获取申明该成员的类
            // m.ReflectedType;//获取用于获取 MemberInfo 的此实例的类对象。 
    
        } 
    }
    复制代码

    T2中的Equals,我们知道这个方式是在Objec中定义的,在TClass中调用的,所以:

    我们发现获取Type对象的成员大多都是以 isxxx、Getxxx、Getxxxs格式的。

    isxxx格式的基本上都是判断是否是某类型。

    Getxxx和Getxxxs都是放回某类型和某类型集合。其中主要的类型有:

    复制代码
    //FieldInfo封装了关于字段的所有信息   (通过Tyep对象的GetFields或GetField方法)
    
    //PropertyInfo类型,封装了类型的属性信息;(通过Type对象的GetProperties或GetProperty方法)
    
    //ConstructorInfo类型,封装了类型的构造函数信息; (..........)
    
    //MethodInfo类型,封装了类型的方法信息;  (........)
    
    //MemberInfo类型,封装了类型的所有公共成员;(**就是我们上面说的GetMembers方法**)
    
    //EventInfo类型,封装了类型的事件信息;(.......)
    
    //ParameterInfo类型,封装了方法和构造函数的参数信息;(........)
    复制代码

    它们都在 System.Reflection 命名空间下,其每个isxxx、Getxxx、Getxxxs的细节实例用法就不一一演示了。和上面的GetMembers用法区别不大。

    动态调用方法

    首先定义个类:

    复制代码
    public class TClass
    {
        public void fun(string str)
        {
            Console.WriteLine("我是fun方法,我被调用了。" + str);
        }
        public void fun2()
        {
            Console.WriteLine("我是fun2方法,我被调用了。");
        }
    
        public static void fun3()
        {
            Console.WriteLine("我是fun3静态方法,我被调用了");
        }
    }
    复制代码

    调用方式一(使用InvokeMember调用方法)

    调用带参实例方法fun

    Type T1 = typeof(TClass);
    T1.InvokeMember("fun", BindingFlags.InvokeMethod, null, new TClass(), new string[] { "test" });

    调用无参实例方法fun2

    Type T1 = typeof(TClass);
    T1.InvokeMember("fun2", BindingFlags.InvokeMethod, null, new TClass(), null);

    调用静态方法

    Type T1 = typeof(TClass);
    T1.InvokeMember("fun3", BindingFlags.InvokeMethod, null, T1, null);

    我们发现了一个问题当我们调用实例方法的时候需要传实例对象过去。(有人会说,都实例对象了,我还要你动态掉调用个屁啊。有种情况,在我们实例了对象后,仍不确定应该调用那个方法时可以只有使用。然后有人有说了,那如果实例对象我也不确定呢?那我们下面会分析连实例对象也给动态了。那接着完下看吧。

    我们来说下这几个参数的意思吧。

    第一个:要被动态调用的方法名。

    第二个:是一个枚举,表示是调用一个方法

    第三个:是Binder,传的是null,使用默认值。

    第四个:传如实例对象(调用实例方法时)或者Type对象(调用静态方法时)。

    第五个:要传给被调用发的参数数组。

    调用方式二(使用MethodInfo.Invoke调用方法)

    Type T1 = typeof(TClass);
    T1.GetMethod("fun", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), new string[] { "testfun1" });
    T1.GetMethod("fun2", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), null);
    T1.GetMethod("fun3", BindingFlags.Static | BindingFlags.Public).Invoke(T1, null);

     

    使用其实和上面的方式一区别不大。

    真正的全动态调用

    上面的两种方式,在编写代码的时候总是要先确定了已知的对象名和方法名。那么我们在不知道对象和方法名的时候是否也可以调用呢?答案是肯定的,实现如下:

    复制代码
    Console.WriteLine("请输入对象类名");
    string className = Console.ReadLine();
    Console.WriteLine("请输入要执行的方法名");
    
    string funName = Console.ReadLine();
    Type T1 = Type.GetType(className);
    
    ConstructorInfo ci = T1.GetConstructors()[0]; //获取构造函数 
    var obj = ci.Invoke(null);//实例化构造函数
    
    T1.InvokeMember(funName, BindingFlags.InvokeMethod, null, obj, null);
    复制代码

    当然,这个代码只能只是fun2,因为上面的传参写死了。(你也可以自己稍微修改下,就可以执行fun、fun2、fun3了) 

    效果如下:(对象名和方法名都是手动输入的

    动态构造对象

    我们先定义一个对象:

    复制代码
    public class TClass
    {
        public TClass()
        {
            Console.WriteLine("构造函数被执行了。。");
        }
        public TClass(string str)
        {
            Console.WriteLine("有参构造函数被执行了。。" + str);
        }        
    }
    复制代码

    动态构造对象

    复制代码
    //动态构造对象,方式一
    Assembly asm = Assembly.GetExecutingAssembly();
    TClass obj = (TClass)asm.CreateInstance("net.tclass", true);//true:不区分大小写
    
    //动态构造对象,方式二
    ObjectHandle handler = Activator.CreateInstance(null, " net.TClass");//null:当前程序集
    obj = (TClass)handler.Unwrap();
    
    //动态构造对象,方式三(构造有参构造函数)
    Assembly asm2 = Assembly.GetExecutingAssembly();
    obj = (TClass)asm2.CreateInstance("net.tclass", true, BindingFlags.Default, null, new string[] { "test" }, null, null);//true:不区分大小写            
    复制代码

    执行效果图:

    获取和修改属性

    复制代码
    var obj = new TClass();
    obj.name = "张三";
    Type type = typeof(TClass);
    //获取属性
    var Name = type.InvokeMember("name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null,
                         obj, new object[] { }) as string;
    Console.WriteLine(obj.name);
    //设置属性
    type.InvokeMember("name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null,
                          obj, new object[] { "新属性(李四)" });
    Console.WriteLine(obj.name);
    
    //=====================
    
    PropertyInfo[] pros = type.GetProperties(---);//
    PropertyInfo pro = null;
    
    var value = pro.GetValue(type);//获取值
    复制代码

    从程序集中获得类型

    取得当前代码所在程序集(使用GetExecutingAssembly)

    Assembly ass = Assembly.GetExecutingAssembly();
    Console.WriteLine("当前所在程序集名:"+ass.ManifestModule.Name);
    Console.WriteLine("当前所在程序集路径:"+ass.Location);

     

    通过反射加载程序集并创建程序中的类型对象

    从程序集中获得类型,这个应该是我们平时用得比较多。如我们所谓的依赖注入和控制反转(这个主题将在下篇博文进行分析)就用到了通过反射从程序集中获取类型。

    首先我们还是看看怎么从程序集中获得类型吧。我们可以使用Assembly类型提供的静态方法LoadFrom()或Load(),如:

    Assembly asm = Assembly.LoadFrom("Demo.dll");
    Assembly asm = Assembly.Load("Demo");

    区别:

    复制代码
    Assembly asm = Assembly.LoadFrom("net.exe");//需要加后缀,可以指定路径,如下面的
    Assembly asm1 = Assembly.LoadFrom(@"C:\01文件\05Svn\BlogsCode\Blogs\Blogs.Web\bin\Blogs.BLL.dll");
    
    Assembly asm2 = Assembly.Load("Blogs.BLL");//无需加后缀,不可以指定路径
    //Assembly asm3 = Assembly.Load(@"C:\01文件\05Svn\BlogsCode\Blogs\Blogs.Web\bin\Blogs.BLL");//这里会报错
    //使用Load可以加载当前程序bin目录行下的程序集或者系统程序集
    
    //这里TClass可以是一个接口,那么可以在外面的dll任意实现了。  
    TClass obj = (TClass)asm2.CreateInstance("net.tclass", true);//true:不区分大小写
    obj.fun();//***调用动态加载的dll中的方法***
    复制代码

    这样带来的功能是非常强大的。如 我们在没有引用程序集的情况下,也可以使用到程序外的程序集。我们还可以根据不同情况引用不同的程序集。我们甚至还可以通过配置文件来直接配置代码运行时应该加载哪个dll,运行哪个dll中的哪个实现方法。(下篇在讲依赖注入的时候会讲到,同学们继续关注哦~)

    从上所知,反射不是某一个概念,而是一类操作的统称。或者说是某些能力的统称。 感觉不好回答反射到底是什么,只能说反射能干什么。它能动态创建对象、动态调用对象方法、动态读取和设置属性和字段、它能动态加载程序外的dll。总的感觉就是大多数都是跟“动态”扯上了关系。

     


     

    补充:跨程序集反射

    如果我们反射A.dll,而A.dll中引用了B.dll,那么在assembly.GetTypes(); //运行到这个地方会弹出如下错误描述

     

    “未处理 System.Reflection.ReflectionTypeLoadException Message="无法加载一个或多个请求的类型。有关更多信息,请检索LoaderExceptions属性。”

     

    这种情况可以

     

    Assembly assembly =  Assembly.LoadFrom("A.dll") ;
    Type type = assembly.GetType("xxx.myclassname") ; //传入对应的需要反射的类型 而不能GetTypes。且,应用程序需要应用A.dll锁依赖的B.dll。

     


    展开全文
  • 反射的基本应用

    万次阅读 2018-12-28 08:28:10
    1,类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实 现对这个类进行初始化。 加载 就是指将 class 文件读入内存,并为之创建一个 Class 对象。...

    原理:反射首先是能够获取到Java中的反射类的字节码,然后将字节码中的方法,变量,构造函数等映射成 相应的 Method、Filed、Constructor 等类
    应用:取出类的modifiers,数据成员,方法,构造器,和超类
    找出某个接口里定义的常量和方法说明.
    取得和设定对象数据成员的值,如果数据成员名是运行时刻确定的也能做到.
    在运行时刻调用动态对象的方法.

    1,类的加载

    当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实
    现对这个类进行初始化。

    • 加载 就是指将 class 文件读入内存,并为之创建一个 Class 对象。 任何类被使用时系统都会建立一个 Class 对象
    • 连接 验证 是否有正确的内部结构,并和其他类协调一致 准备 负责为类的静态成员分配内存,并设置默认初始化值 解析 将类的二进制数据中的符号引用替换为直接引用
    • 初始化

    1.2类的初始化

    1. 创建类的实例
    2. 类的静态变量,或者为静态变量赋值
    3. 类的静态方法
    4. 使用反射方式来强制创建某个类或接口对应的 java.lang.Class 对象
    5. 初始化某个类的子类

    1.3反射概述

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

    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖这个类,使用的就是 Class 类中的方法,所以先要获取到每一个字节码文件所对应的 Class 类型对象。

    1.4准备数据,我就用我现在的写的项目的数据,大家随意

    在这里插入图片描述

    1.5 知识储备

    需要掌握 6 个单词

    • Class 类
    • Constructor 构造
    • Method 方法
    • Filed 字段
    • instance 实例
    • invoke 执行

    1.6 Class 获得方式

    在这里插入图片描述

    public class A {
        /**
         * class获得方式
         *
         * @param args
         */
        public static void main(String[] args) {
            //1 通过类型获得
            // 语法:类名.class
            // 应用场景:确定类型 等
            Class clazz1 = BrandController.class;
            System.out.println("语法:类名.class|" + clazz1);
    
            //2 通过实例对象获得
            // 语法:变量.getClass()
            // 应用场景:在方法内部通过参数获得类型 等
            BrandController brandController = new BrandController();
            Class<? extends BrandController> aClass = brandController.getClass();
            System.out.println("语法:变量.getClass()|" + aClass);
    
    
            //3 通过字符串获得
            // 语法:Class.forName("全限定类名")
           // 应用场景:通过配置获得字符串 等
            try {
                Class<?> aClass1 = Class.forName("com.controller.BrandController");
                System.out.println("Class.forName(\"全限定类名\")|"+aClass1);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
        }
    
    
    }
    
    

    1.6.1 得到这个类的名字

    在这里插入图片描述

          //1 获得 Class
           Class clazz = User.class;
           // 得到这个类的名字:全限定类名
            String name = clazz.getName();
            //  这个只是类的名字
            String simpleName = clazz.getSimpleName();
            System.out.println(" 这个只是类的名字simpleName:"+simpleName);
    
            System.out.println("得到这个类的名字:全限定类名name:"+name);
    
    
    
    
    

    1.7构造方法与实例

    在这里插入图片描述

    public class A {
        /**
         * 构造方法与实例
         *
         * @param args
         */
        public static void main(String[] args) {
            //无参构造 , 并实例化
    
            //1 获得 Class
            Class<SpecificationOption> specificationOptionClass = SpecificationOption.class;
            System.out.println("获得 Class"+specificationOptionClass);
            //2 获得构造 -- 没有形参
            Constructor<SpecificationOption> constructor = null;
            try {
                constructor = specificationOptionClass.getConstructor();
                System.out.println("获得构造 -- 没有形参"+constructor);
                SpecificationOption specificationOption = constructor.newInstance();
                System.out.println("实例对象,没有实参"+specificationOption);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    获取无参的简化版

    在这里插入图片描述

    
    public class A {
        /**
         * 构造方法与实例
         *
         * @param args
         */
        public static void main(String[] args) {
            //无参构造 , 并实例化
    
            //1 获得 Class
            try {
                // 获得无参的简化版
                SpecificationOption specificationOption = SpecificationOption.class.newInstance();
                System.out.println(specificationOption);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
    
        }
    }
    

    获取有参构造

    在这里插入图片描述
    在这里插入图片描述

    public static void main(String[] args) {
            //有参构造 , 并实例化
            //1 获得 Class
            Class beanClass = SpecificationOption.class;
            //2 获得构造 -- 三个字符串形参 -- (Integer.class,String.class,Integer.class)
            Constructor constructor = null;
            try {
                constructor = beanClass.getConstructor(Integer.class, String.class, Integer.class);
                System.out.println("获得构造 -- 三个字符串形参" + constructor);
                //3 实例对象,三个字符串实参
                Object o = constructor.newInstance(2323,"白色", 1);
                System.out.println(o);
            } catch (Exception e) {
                e.printStackTrace();
    
            }
    
        }
    

    1.7.5 扩展:私有构造(暴力反射)

    • 修改 Bean 添加私有构造
    private Bean(String id) {
    this.id = id;
    System.out.println("有参构造:" + id);
    }
    
    • getConstructor() 使用该方法将无法获得私有方法,程序运行抛异常
    • 在这里插入图片描述
    • 没有使用 setAccessible(true),将抛异常
    • 在这里插入图片描述
      在这里插入图片描述
    @Test
    public void testPrivateCons() throws Exception{
    //私有构造
    //1 获得 Class
    Class beanClass = Bean.class;
    //2 获得构造 -- 两个字符串形参 -- Bean(String id, String className)
    // * getConstructor() 将抛异常 java.lang.NoSuchMethodException
    // * getDeclaredConstructor 可以获得私有构造
    Constructor constructor = beanClass.getDeclaredConstructor(String.class)
    //暴力访问
    constructor.setAccessible(true);
    //3 实例对象,两个字符串实参
    Object bean = constructor.newInstance("userId");
    System.out.println(bean);
    
    

    1.8方法与执行

    1.8.1public 方法
    • 获得方法并设置
      在这里插入图片描述
      //1 获得 Class
            Class clazz = User.class;
            //2 获得实例 ,相当于 Object obj = new Bean();
            Object obj = clazz.newInstance();
            //3 操作 setAge 方法
            // * 格式:getMethod(方法名,形成列表)
            Method setMethod = clazz.getMethod("setAge", Integer.class);
    
            System.out.println("getMethod(方法名,形成列表)"+setMethod);
            //3.2 执行方法,一个实参
            Object setReturnObj = setMethod.invoke(obj, 12);
            System.out.println("set 方法返回值:" + setReturnObj);
    
    
    1.8.2私有方法(暴力反射)private

    添加私有方法
    在这里插入图片描述

    在这里插入图片描述

    
            //4 操作 getId 方法
            // 4.1 获得方法,没有形参
            Method getMethod = clazz.getMethod("getAge");
            // 4.2 执行方法,没有实参
            Object getReturnObj = getMethod.invoke(obj);
            System.out.println("get 方法返回值:" + getReturnObj);
    
    
             //5 暴力反射私有的构造方法
            Method showMethod = clazz.getDeclaredMethod("show");
            System.out.println("暴力反射私有的构造方法show     "+showMethod);
             //暴力访问
            showMethod.setAccessible(true);
              // 4 执行方法,没有实参
            // obj.setMethod(args)     user.setAge(20)
            Object invoke = setMethod.invoke(obj, 20);
            Object result = showMethod.invoke(obj);
            System.out.println("show私有"+result);
    

    1.8.3 main 方法与执行

    添加main方法
    在这里插入图片描述

    在这里插入图片描述

     //有参构造 , 并实例化
            Class<User> clazz = User.class;
            //2 获得方法 -- main 静态方法 -- public static void main(String[] args)
            Method mainMethod = clazz.getMethod("main", String[].class);
            Object getReturnObj =  mainMethod.invoke(null, (Object)new String[]{"aaa","bbb"});
            System.out.println("main 方法返回值:|||||||||" + getReturnObj);
    

    1.8.4 public 字段的操作

    在这里插入图片描述

    
      //5 操作字段,进行赋值,public String  name;
            //5.1 获得的字段,一个形参
            // * 格式:getField(字段名)
            Field descriptionField = clazz.getField("name");
            System.out.println("getField(字段名)     "+descriptionField);
    
            //5.2 为对象的字段赋值
            descriptionField.set(obj, "喜欢在文字中倾诉");
    
            //5.3 获取对象的字段值
            Object fieldReturnObj = descriptionField.get(obj);
            System.out.println("description 字段返回值:       "+fieldReturnObj);
    
    
    

    1.8.5 private 字段的操作

    在这里插入图片描述

    在这里插入图片描述

       //5 操作字段,进行赋值,private String  name;
            //5.1 获得的字段,一个形参
            // * 格式:getDeclaredField(字段名)
            Field descriptionField = clazz.getDeclaredField("name");
            System.out.println("getDeclaredField(字段名)     "+descriptionField);
            //暴力访问
            descriptionField.setAccessible(true);
            //5.2 为对象的字段赋值
            descriptionField.set(obj, "喜欢在文字中倾诉");
    
            //5.3 获取对象的字段值
            Object fieldReturnObj = descriptionField.get(obj);
            System.out.println("description 字段返回值:       "+fieldReturnObj);
    
    
    展开全文
  • 反射

    2020-10-22 21:39:18
    反射 1、概念 反射是java的动态机制,在运行状态中对于任意一个类,都能知道这个类所有的属性、方法、构造器。很多优秀的开源框架都是通过反射机制完成。 2、可以实现的功能 ​ ①在运行时判断任意一个对象所属的类...
  • 反射概念

    千次阅读 2019-07-09 14:57:59
    类的加载概述和加载时机 类的加载概述 类的加载是指: 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类的初始化. 加载: 指的是将Javac创建的class文件读入...
  • Java反射技术详解

    万次阅读 多人点赞 2019-04-14 23:11:32
    相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有...
  • 用最直接的大白话来聊一聊Java中的反射机制

    万次阅读 多人点赞 2019-05-26 22:44:15
    思考:在讲反射之前,先思考一个问题,java中如何创建一个对象,有哪几种方式? Java中创建对象大概有这几种方式: 1、使用new关键字:这是我们最常见的也是最简单的创建对象的方式 2、使用Clone的方法:无论何时...
  • 细说反射,Java 和 Android 开发者必须跨越的坎

    万次阅读 多人点赞 2017-07-06 23:36:13
    但是,我已经写了注解和动态代理这两个知识点的博客,阅读量还可以,这两个知识点是属于反射机制中的,现在对于注解和动态代理息息相关的反射知识基础我倒是退缩了,所以说看起来很普通的东西,其实真的要一五一十地...
  • java反射知识点小结

    万次阅读 2019-05-04 15:54:19
    参考代码:https://github.com/ZhangXiaoixiang/reflectdemo 说明:收集的网上资料,自己整理收集 视频教程(腾讯课堂): ...term_id=100354189&taid=2094161629319039&vid=t1426y3hmo...
  • 面试官:反射都不会,还敢说自己会Java?

    万次阅读 多人点赞 2020-04-29 15:50:03
    一、反射机制 1.1 框架   在学习Java的路上,相信你一定使用过各种各样的框架。所谓的框架就是一个半成品软件,已经对基础的代码进行了封装并提供相应的API。在框架的基础上进行软件开发,可以简化编码。学习使用...
  • Java笔试面试-反射和动态代理

    万次阅读 多人点赞 2019-09-19 09:28:41
    反射   反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect)的能力。简单来说就是通过反射,可以在运行期间获取、检测和调用对象的属性和方法。 反射的使用场景 1.编程工具 IDEA 或 ...
  • Java基础篇:反射机制详解

    万次阅读 多人点赞 2018-09-29 10:19:50
    一、什么是反射反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行的时候才动态加载类,并且对于任意一个类,都能够知道这个类的所有属性和方法,调用方法/访问属性,不需要提前在编译期...
  • Java反射机制的原理和用途

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

    万次阅读 多人点赞 2017-11-26 10:35:36
    Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为Java 的反射...
  • Java 反射 -超详细讲解(附源码)

    万次阅读 多人点赞 2018-10-29 11:14:52
    之前也有学习过反射,可是很快就忘了,也不知道有什么用,怎么用,故特此写下此文,以加深对java反射的理解 1:反射概述 &amp;amp;amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;amp;amp;nbsp;...
  • java 反射

    千次阅读 2016-07-28 16:50:30
    不管咋样,学java的,了解java反射非常有必要!什么是反射反射定义java官方文档给出了解释: Reflection is the ability of a program to query and modify its state during the execution. 意为:反射是在程序运行...
  • BGP路由反射器RR

    千次阅读 多人点赞 2020-06-23 13:46:35
    曾子曰:“吾日三省吾身:为人谋而不忠乎?与朋友交而不信乎?...对于大型网络来说,使用路由反射器可以大大减少 IBGP 对等体关系的数量。路由反射器的使用,会明显减少配置工作量,人为出错的可能性也会大大降低。
  • Java核心:第一章:Java反射

    万次阅读 多人点赞 2020-05-11 11:04:34
    首先学习反射之前,我要提出疑问: 反射是个什么东西?它是用来做什么的?为啥要用它?它有什么优缺点?它的工作原理是什么?平时的应用场景有哪些?我怎么使用它?(何时用,怎么用,为啥要用等等) 这么多的问题...
  • 反射获取class的3种方式

    万次阅读 2020-06-09 19:23:11
    package com.example; class User{ int name; } public static void main(String[] args) { //方式一 类的全路径获取class try { Class<?> aClass = Class.for... } catch (ClassNotFoundException e) {
1 2 3 4 5 ... 20
收藏数 497,560
精华内容 199,024
关键字:

反射