精华内容
下载资源
问答
  • 大家都知道正常调用是不可以访问对象的private修饰的属性和方法的,这也是Java的封装性原则。 但是有没有方法可以强制去访问对象的private修饰的属性和方法呢?那就是用反射!(这个可能在面试题中被问到哦) 接...

    大家都知道正常的调用是不可以访问对象的private修饰的属性和方法的,这也是Java的封装性原则。

    但是有没有方法可以强制去访问对象的private修饰的属性和方法呢?那就是用反射!(这个可能在面试题中被问到哦)

    接下来就来看看是如何实现的:

    我们先去jdk里看一下描述属性的类Field,和方法的类Method:

    java.lang.reflect

    Class Field

    java.lang.reflect

    Class Method


    可以看到这两个类有个共通的特点,就是他们都继承自java.lang.reflect.AccessibleObject这个类,我们好好看看这个类的描述

    java.lang.reflect

    Class AccessibleObject

    • All Implemented Interfaces:
      AnnotatedElement
      Direct Known Subclasses:
      ConstructorFieldMethod


      public class AccessibleObject
      extends Object
      implements AnnotatedElement
      The AccessibleObject class is the base class for Field, Method and Constructor objects. It provides the ability to flag a reflected object as suppressing default Java language access control checks when it is used. The access checks--for public, default (package) access, protected, and private members--are performed when Fields, Methods or Constructors are used to set or get fields, to invoke methods, or to create and initialize new instances of classes, respectively.

    大致意思就是:

    这个AccessibleObject类是Field, Method and Constructor对象的一个父类,他可以让一个反射对象去禁止Java语言的访问控制检测。控制检测有public, default (package) access, protected, and private。。。blah blah blah。。。

    这里我贴出控制访问控制检测的这个方法:(这个类里还有一些相关的方法,有兴趣的大家可以自己去看看)

     

    setAccessible

    public void setAccessible(boolean flag)
                       throws SecurityException
    Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of falseindicates that the reflected object should enforce Java language access checks.

    大致意思:

    设置标志去指示对象的boolean值,如果是true则禁止java访问控制检查,如果是false则强制反射对象使用java访问控制检查


    知道了这个方法就可以做一个小例子测试一下啦。

    下面这个例子很简单,就是定义一个dog类,里面有个private的属性dogName,和private的方法say。

    main函数里用反射先去修改dogName,然后在调用say方法打印出来:

    1. public class Test2 {  
    2.   
    3.     public static void main(String[] args) throws Exception {  
    4.         //获得Dog类的Class对象  
    5.         Class<?> classType = Class.forName("Dog");  
    6.         //生成对象的实例  
    7.         Object obj = classType.newInstance();  
    8.           
    9.         //取得dogName属性  
    10.         Field dogName = classType.getDeclaredField("dogName");  
    11.         //禁止Field的访问控制检查  
    12.         dogName.setAccessible(true);  
    13.         //将Field的值设为“Xiao Qiang”  
    14.         dogName.set(obj, "Xiao Qiang");  
    15.           
    16.         //取得say()方法  
    17.         Method say = classType.getDeclaredMethod("say", new Class[]{});  
    18.         //禁止say方法的访问控制检查  
    19.         say.setAccessible(true);  
    20.         //调用say方法  
    21.         say.invoke(obj, new Object[]{});  
    22.     }  
    23.   
    24. }  
    25.   
    26.  class Dog {  
    27.     //私有的属性  
    28.     private String dogName = "Wang Cai";  
    29.     //私有的方法  
    30.     private void say() {  
    31.         System.out.println(dogName + ": Wang Wang");  
    32.     }  
    33. }  

    输出结果:Xiao Qiang: Wang Wang

    这里需要特别注意一个地方:

    如果想用反射修改访问控制检查的话,获取Method和Field对象的时候一定要用getDeclaredField和getDeclaredMethod。不要用getField和getMethod。

    虽然这两个方法的参数都是相同的,但不同点在于getMethod和getField只能获得public修饰的属性和方法。而getDeclared可以获取任何类型的属性和方法,因为这个例子要调用私有的属性和方法,所以要用getDeclaredXX。

    转载于:https://www.cnblogs.com/Free-Thinker/p/6397401.html

    展开全文
  • 今天在项目中遇到一个由于Java反射调用Bean方法而导致Spring特性失效的问题,折腾了半天,现给出解决方案。 1、抛出问题 我要在控制器的某个方法中通过反射调用一个service的方法,但是这个方法已经被纳入切面同时该...

    今天在项目中遇到一个由于Java反射调用Bean方法而导致Spring特性失效的问题,折腾了半天,现给出解决方案。

    1、抛出问题

    我要在控制器的某个方法中通过反射调用一个service的方法,但是这个方法已经被纳入切面同时该方法也依赖于其他通过Spring自动注入的Bean实例,准备代码如下:

    1.1、编写TestAspectController类

    @RestController
    public class TestAspectController {
        @GetMapping("/testAspect")
        public Object testAspect() throws NoSuchMethodException {
            try {
    			//通过完整类名反射加载类
                Class cla = Class.forName("com.icypt.learn.service.TestAspectService");
    			//取得类实例
                Object obj = cla.newInstance();
    			//通过实例反射调用sayHello方法
                obj.getClass().getDeclaredMethod("sayHello").invoke(obj);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return "ok";
        }
    }
    

    1.2、编写ModuleService类

    @Service
    public class ModuleService {
    }
    

    1.3、编写TestKey注解

    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface TestKey {
        String key() default "";
    }
    

    1.4、编写TestAspectService

    @Component
    public class TestAspectService {
        @Autowired
        private ModuleService moduleService;
        @TestKey(key = "key")
        public void sayHello() {
            System.out.println("************--->************" + moduleService);
        }
    }
    

    1.5、编写TestAspect切面

    @Aspect
    @Component
    public class TestAspect {
        @Pointcut("@annotation(com.icypt.learn.aspect.TestKey)")
        public void process() {
        }
        @Before("process()")
        public void boBefore() {
            System.out.println("********before*********");
        }
        @After("process()")
        public void doAfter() {
            System.out.println("********after*********");
        }
    }
    

    运行结果:

    2019-03-28 21:57:26.548  INFO 30348 --- [nio-8082-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
    2019-03-28 21:57:26.548  INFO 30348
     --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started 2019-03-28 21:57:26.587  INFO 30348
     --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 39 ms
    ************--->************null
    根据结果可以发现,切面没有被执行,同时依赖注入的Bean也没有获得实例,其实原因很简单,就是因为我们是手动通过反射获得的Bean的实例,这种方式相当于我们new Bean(),此Bean的实例已完全脱离Spring容器,所以Spirng无法感知它的存在,那么如何解决呢? 
    

    2、解决问题

    2.1、编写SpringContextUtil类

    @Component
    public class SpringContextUtil implements ApplicationContextAware {
          // Spring应用上下文环境  
        private static ApplicationContext applicationContext;
          /** 
         * 实现ApplicationContextAware接口的回调方法,设置上下文环境 
         *  
         * @param applicationContext 
         */  
        public void setApplicationContext(ApplicationContext applicationContext) {  
            SpringContextUtil.applicationContext = applicationContext;  
        }  
          /** 
         * @return ApplicationContext 
         */  
        public static ApplicationContext getApplicationContext() {  
            return applicationContext;  
        }  
          /** 
         * 获取对象 
         *  
         * @param name 
         * @return Object
         * @throws BeansException 
         */  
        public static Object getBean(String name) throws BeansException {
            return applicationContext.getBean(name);  
        }
        public static Object getBean(String name, Class cla) throws BeansException {
            return applicationContext.getBean(name, cla);
        }
    }
    

    此类的作用就是手动通过BeanId获取Bean实例。

    2.2、修改TestAspectController类

    @RestController
    public class TestAspectController {
        @GetMapping("/testAspect")
        public Object testAspect() throws NoSuchMethodException {
            try {
    			//通过完整类名反射加载类
                Class cla = Class.forName("com.icypt.learn.service.TestAspectService");
                //获取首字母小写类名
                String simpleName = cla.getSimpleName();
                String firstLowerName = simpleName.substring(0,1).toLowerCase()
     + simpleName.substring(1);
                //通过此方法去Spring容器中获取Bean实例
                Object obj = SpringContextUtil.getBean(firstLowerName, cla);
    			//通过实例反射调用sayHello方法
                obj.getClass().getDeclaredMethod("sayHello").invoke(obj);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return "ok";
        }
    }
    

    其他类保持不变,运行结果如下:

    2019-03-28 22:13:59.311  INFO 37252 --- [nio-8082-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
    2019-03-28 22:13:59.312  INFO 37252 
    --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started 2019-03-28 22:13:59.350  INFO 37252 
    --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
    ********before*********
    ************--->************com.icypt.learn.service.ModuleService@5681f667
    ********after*********
    

    通过结果可以发现,注入的Bean已经获得了实例同时切面也友好的执行,问题完美解决。解决问题核心思想就是我们通过Spring的反射机制获得Bean的实例化对象,而后通过Java的反射机制携带该实例对象去处理业务,这样就不会使Bean脱离Spring容器管理,当然也可以享有Spring的Bean所有拥有的特性。

    展开全文
  • 大家都知道正常调用是不可以访问对象的private修饰的属性和方法的,这也是java的封装性原则。 但是有没有方法可以强制去访问对象的private修饰的属性和方法呢?那就是用反射!(这个可能在面试题中被问到哦) ...

    大家都知道正常的调用是不可以访问对象的private修饰的属性和方法的,这也是java的封装性原则。

    但是有没有方法可以强制去访问对象的private修饰的属性和方法呢?那就是用反射!(这个可能在面试题中被问到哦)

    下面这个例子很简单,就是定义一个dog类,里面有个private的属性dogName,和private的方法say。

    main函数里用反射先去修改dogName,然后在调用say方法打印出来:

    源代码1:

    package com.imooc.reflect;
    
    public class Dog {
    	//私有的域
    	private String dogName="小风";
    	//私有的方法
    	private void say(){
    		System.out.println(dogName+":汪汪~~~");
    	}
    }
    

    源代码2:

    package com.imooc.reflect;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class DogTest {
    
    	public static void main(String[] args) throws Exception{
    		//获取Dog类的Class对象
    		Class class1 = Class.forName("com.imooc.reflect.Dog");
    		//生成对象的实例
    		Object object = class1.newInstance();
    		
    		//取得dogName域
    		Field dogName = class1.getDeclaredField("dogName");
    		//禁止Field的访问控制检查
    		dogName.setAccessible(true);
    		//将Field的值设为"小强";
    		dogName.set(object, "小强");
    		
    		//取得say()方法
    		Method say = class1.getDeclaredMethod("say", new Class[]{});
    		//禁止say方法的访问检查
    		say.setAccessible(true);
    		//调用say方法
    		say.invoke(object, new Object[]{});
    	}
    }
    

    这里需要特别注意一个地方:

    如果想用反射修改访问控制检查的话,获取Method和Field对象的时候一定要用getDeclaredField和getDeclaredMethod。不要用getField和getMethod。

    虽然这两个方法的参数都是相同的,但不同点在于getMethod和getField只能获得public修饰的属性和方法。而getDeclared可以获取任何类型的属性和方法,因为这个例子要调用私有的属性和方法,所以要用getDeclaredXX。


    展开全文
  • 一、 通过反射调用类中的方法正常qingk

    一、 通过反射调用类中的方法

    在正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可得到Method对象。

    public Method getMethod(String name,
                            Class<?>... parameterTypes)
                     throws NoSuchMethodException,
                            SecurityException
    当获取到Method对象后,可以通过该对象来执行方法,但是在方法调用的时候,因为会牵扯到方法中参数的问题,所以通过getMethod()取得的时候,必须设置好参数类型。

    package org.chen.yuan.reflect;
    interface China{	// 定义China接口
    	public static final String NATIONAL = "China" ;	// 定义全局常量
    	public static final String AUTHOR = "李兴华" ;	// 定义全局常量
    	public void sayChina() ;		// 无参的,没有返回值的方法
    	public String sayHello(String name,int age) ;	// 定义有两个参数的方法,并返回内容
    }
    public class Person implements China{
    	private String name ;
    	private int age ;
    	public Person(){	// 无参构造
    	}
    	public Person(String name){
    		this.name = name ;	// 设置name属性
    	}
    	public Person(String name,int age){
    		this(name) ;
    		this.age = age ;
    	}
    	public void sayChina(){	// 覆写方法
    		System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;
    	}
    	public String sayHello(String name,int age){
    		return name + ",你好!我今年:" + age + "岁了!" ;
    	}
    	public void setName(String name){
    		this.name = name ;
    	}
    	public void setAge(int age){
    		this.age = age ;
    	}
    	public String getName(){
    		return this.name ;
    	}
    	public int getAge(){
    		return this.age ;
    	}
    };
    我们调用sayChina()方法,此方法中没有任何参数。

    执行调用的方法,需通过Method的invoke方法来实现:

    public Object invoke(Object obj,
                         Object... args)
                  throws IllegalAccessException,
                         IllegalArgumentException,
                         InvocationTargetException

    示例1:(调用无参的方法)

    package org.chen.yuan.reflect;
    interface China{	// 定义China接口
    	public static final String NATIONAL = "China" ;	// 定义全局常量
    	public static final String AUTHOR = "沉缘" ;	// 定义全局常量
    	public void sayChina() ;		// 无参的,没有返回值的方法
    	public String sayHello(String name,int age) ;	// 定义有两个参数的方法,并返回内容
    }
    public class Person implements China{
    	private String name ;
    	private int age ;
    	public Person(){	// 无参构造
    	}
    	public Person(String name){
    		this.name = name ;	// 设置name属性
    	}
    	public Person(String name,int age){
    		this(name) ;
    		this.age = age ;
    	}
    	public void sayChina(){	// 覆写方法
    		System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;
    	}
    	public String sayHello(String name,int age){
    		return name + ",你好!我今年:" + age + "岁了!" ;
    	}
    	public void setName(String name){
    		this.name = name ;
    	}
    	public void setAge(int age){
    		this.age = age ;
    	}
    	public String getName(){
    		return this.name ;
    	}
    	public int getAge(){
    		return this.age ;
    	}
    };

    我们在Person.java 类中定义了一个无参方法sayChina和一个有参数的方法sayHello,接下来,我们调用无参数的方法:

    package org.chen.yuan.reflect;
    
    import java.lang.reflect.Method;
    
    public class InvokeSyaChinaDemo
    {
        public static void main(String[] args)
        {
            Class<?> c1 = null;
            try
            {
                c1 = Class.forName("org.chen.yuan.reflect.Person");
                Method met = c1.getMethod("sayChina");
                met.invoke(c1.newInstance());
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    输出: 作者:沉缘,国籍:China

    可以看出,通过上述反射的方式,我们能够顺利的调用Person类中的方法。 那思考下,如果我们要调用含有参数的方法sayHello,该如何做呢?

    可以想象,如果方法里存在了参数,则必须设置参数的类型及内容。

    public class InvokeSayHelloDemo
    {
    
        public static void main(String[] args) throws Exception
        {
            Class<?> c1 = null;
            c1 = Class.forName("org.chen.yuan.reflect.Person");
            Method met = c1.getMethod("sayHello", String.class, int.class);
            String result = (String) met.invoke(c1.newInstance(), "沉缘", 25);
            System.out.println(result);
        }
    
    }

    输出: 沉缘,你好!我今年:25岁了!


    二、 通过反射调用类中的setter及getter方法

    setter和getter方法是访问类属性的标准方法,如果一个类中的属性被封装,则必须通过setter及getter方法设设置和取得,实际上此方法的操作之所以要这样规定,主要是由于反射机制可以给予支持。

    通过反射可以调用setter及getter方法。

    package org.chen.yuan.reflect;
    
    import java.lang.reflect.Method;
    
    public class InvokeSetGetDemo
    {
    
        public static void main(String[] args) throws Exception
        {
            Class<?> c1 = null;
            Object obj = null;
    
            c1 = Class.forName("org.chen.yuan.reflect.Person");
            obj = c1.newInstance();
    
            setter(obj, "name", "沉缘", String.class);
            getter(obj, "name");
    
            setter(obj, "age", 25, int.class);
            getter(obj, "age");
        }
    
        /**
         * @param obj 要操作的对象
         * @param att 要操作的属性
         * @param value 要设置的属性数据
         * @param type 要设置的属性的类型
         */
        public static void setter(Object obj, String att, Object value, Class<?> type)
        {
            try
            {
                Method met = obj.getClass().getMethod("set" + initStr(att), type);
                met.invoke(obj, value);
    
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
        /**
         * @param obj 要操作的对象
         * @param att 要操作的属性
         */
        public static void getter(Object obj, String att) throws Exception
        {
            Method met = obj.getClass().getMethod("get" + initStr(att));
            System.out.println(met.invoke(obj));
        }
    
        /**
         * 将单词首字母大写
         * 
         * @param old
         * @return
         */
        public static String initStr(String old)
        {
            String newStr = old.substring(0, 1).toUpperCase() + old.substring(1);
            return newStr;
        }
    }


    三、 通过反射调用属性

    如果假设要操作一个类中的属性,则也可以通过Field完成,而不必麻烦的通过setter和getter。Class类中,获取类中Field的方法:

    1) 得到类中公共属性

    public Field getField(String name)
                   throws NoSuchFieldException,
                          SecurityException
    2)得到本类属性

    public Field getDeclaredField(String name)
                           throws NoSuchFieldException,
                                  SecurityException

    而在Field类中,提供了获取属性内容及设置属性内容的方法:

    1) 获取属性内容

    public Object get(Object obj)
               throws IllegalArgumentException,
                      IllegalAccessException
    2) 设置属性内容

    public void set(Object obj,
                    Object value)
             throws IllegalArgumentException,
                    IllegalAccessException

    还有一点需要注意,访问类中的私有属性时,必须要让该属性对外可见:

    public void setAccessible(boolean flag)
                       throws SecurityException
    该方法继承自Field的父类:
    java.lang.reflect

    Class AccessibleObject

    只要把该方法的参数内容设置为true即可。

    public class InvokeFieldDemo
    {
        public static void main(String args[]) throws Exception
        {
            Class<?> c1 = null;
            Object obj = null;
            c1 = Class.forName("org.chen.yuan.reflect.Person"); // 实例化Class对象
            obj = c1.newInstance();
            Field nameField = null;
            Field ageField = null;
            nameField = c1.getDeclaredField("name"); // 取得name属性
            ageField = c1.getDeclaredField("age"); // 取得name属性
            nameField.setAccessible(true); // 此属性对外部可见
            ageField.setAccessible(true); // 此属性对外部可见
            nameField.set(obj, "沉缘"); // 设置name属性内容
            ageField.set(obj, 25); // 设置age属性内容
            System.out.println("姓名:" + nameField.get(obj));
            System.out.println("年龄:" + ageField.get(obj));
        }
    };


    输出: 

    姓名:沉缘
    年龄:25

    可见,操作属性,未必需要setter和getter方法的支持,但是,为了保证程序的安全性,最好还是通过setter和getter方法对属性进行操作。


    四、 通过反射操作数组

    反射机制不光能用在类中,也可以应用在任意的引用数据类型上,当然,这就包含了数组,数组使用Array类完成。

    Class类中存在以下一个方法:

    public Class<?> getComponentType()

    Array类中得到数组指定下标的内容:

    public static Object get(Object array,
                             int index)
                      throws IllegalArgumentException,
                             ArrayIndexOutOfBoundsException

    Array类中修改内容:

    public static void set(Object array,
                           int index,
                           Object value)
                    throws IllegalArgumentException,
                           ArrayIndexOutOfBoundsException

    Array类中开辟新的数组:

    public static Object newInstance(Class<?> componentType,
                                     int... dimensions)
                              throws IllegalArgumentException,
                                     NegativeArraySizeException

    取得数组信息并修改内容:

    package org.chen.yuan.reflect;
    import java.lang.reflect.Array ;
    public class ClassArrayDemo{
    	public static void main(String args[]) throws Exception{
    		int temp[] = {1,2,3} ;// 声明一整型数组
    		Class<?> c = temp.getClass().getComponentType() ;	// 取得数组的Class对象
    		System.out.println("类型:" + c.getName()) ;	// 取得数组类型名称
    		System.out.println("长度:" + Array.getLength(temp)) ;
    		System.out.println("第一个内容:" + Array.get(temp,0)) ;
    		Array.set(temp,0,6) ;
    		System.out.println("第一个内容:" + Array.get(temp,0)) ;
    	}
    };
    输出:

    类型:int
    长度:3
    第一个内容:1
    第一个内容:6


    数组修改的过程,实际上就是创建一个新的数组的过程,所以要把旧的数组内容拷贝到新的数组中去。

    package org.chen.yuan.reflect;
    
    import java.lang.reflect.Array;
    
    public class ChangeArrayDemo
    {
        public static void main(String args[]) throws Exception
        {
            int temp[] = {1, 2, 3};// 声明一整型数组
            int newTemp[] = (int[]) arrayInc(temp, 5); // 重新开辟空间5
            print(newTemp);
            System.out.println("\n-------------------------");
            String t[] = {"chenyuan", "wuqing", "lengxue"};
            String nt[] = (String[]) arrayInc(t, 8);
            print(nt);
        }
    
        public static Object arrayInc(Object obj, int len)
        {
            Class<?> c = obj.getClass();
            Class<?> arr = c.getComponentType(); // 得到数组的
            Object newO = Array.newInstance(arr, len); // 开辟新的大小
            int co = Array.getLength(obj);
            System.arraycopy(obj, 0, newO, 0, co); // 拷贝内容
            return newO;
        }
    
        public static void print(Object obj)
        { // 数组输出
            Class<?> c = obj.getClass();
            if (!c.isArray())
            { // 判断是否是数组
                return;
            }
            Class<?> arr = c.getComponentType();
            System.out.println(arr.getName() + "数组的长度是:" + Array.getLength(obj)); // 输出数组信息
            for (int i = 0; i < Array.getLength(obj); i++)
            {
                System.out.print(Array.get(obj, i) + "、"); // 通过Array输出
            }
        }
    };

    输出:

    nt数组的长度是:5
    1、2、3、0、0、
    -------------------------
    java.lang.String数组的长度是:8
    chenyuan、wuqing、lengxue、null、null、null、null、null、


    展开全文
  • 一、 通过反射调用类中的方法正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可得到Method对象。...
  • 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个cls参数表示这个类,可以使用类属性 ...
  • 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个cls参数表示这个类,可以使用类属性 ...
  • 反射提供的是runtime阶段获取类的class实例、方法、属性、注解,并且能够调用类的方法的途径,这种动态获取类信息和调用方法的机制被称之为反射 为什么要使用反射正常的实例化一个对象 ClassA objA = new ...
  • 提到java语言的高级特性,反射...正常场景下,java从源码到运行有3个阶段:source class runtime反射提供的是runtime阶段获取类的class实例、方法、属性、注解,并且能够调用类的方法的途径,这种动态获取类信息调...
  • 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个cls参数表示这个类,可以使用类属性 ...
  • 面向对象之反射及内置方法...静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个cls参数表...
  • 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个cls参数表示这个类,可以使用类属性 ...
  • 方法的名称参数列表才能唯一地决定某个方法 方法反射操作:method.invoke(对象,参数列表) ...2.方法反射的好处就是解耦,比如说a,b,c对象都要调用 print()方法正常的想法就是要创建每个对象,...
  • 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个cls参数表示这个类,可...
  • 面向对象之反射及内置方法 ...静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点:  类方法必须有一个...
  • 正常来说,我们调用对象的方法是通过dot运算符来进行的,这里我们介绍另一种方法,有以下几个步骤:1,...这里要特别注意下getMethod方法和invoke方法的参数,见下面的例子 1 package reflectTest; 2 3 i...
  • .Net学习之反射

    2018-02-22 17:00:44
    反射 DLL的组成 反射加载DLL 正常方法Common非反射 ...通过反射调用方法 反射调用构造方法 反射调用实例方法静态方法私有方法泛型方法MVC控制器采用的模式 反射字段属性分别获取值设置值 反射的好处局限...
  • 都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任何一个方法和属性这种动态获取的信息以及动态调用对象的方法的功能成为Java的反射机制。 那么反射机制的存在跟private访问修饰矛盾

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 140
精华内容 56
关键字:

反射调用方法和正常调用方法