精华内容
下载资源
问答
  • java反射——关于权限和异常

    千次阅读 2016-09-14 14:31:46
    使用Java反射API的一个重要好处是可以绕过Java语言中默认的访问控制权限。Constructor、Filed和Method都继承自java.lang.reflect.AccessibleObject,其中的setAccessible方法可以用于设置是否绕过默认的权限检查,...
      使用Java反射API的一个重要好处是可以绕过Java语言中默认的访问控制权限。Constructor、Filed和Method都继承自java.lang.reflect.AccessibleObject,其中的setAccessible方法可以用于设置是否绕过默认的权限检查,否则,访问非public的方法或者字段将产生IllegalAccessException异常。
    
        而在利用Invoke方法来调用方法是,如果方法本身抛出异常,invoke方法将抛出InvocationTargetException异常,通过getCause方法可以获取实际的异常信息。
        在Java7中,为所有与反射相关的异常类添加了一个统一的父类java.lang.ReflectiveOperationException,在处理反射相关的异常时可以直接捕获该异常而不用分别捕获各个异常子类。

    关于Java动态性,除了反射机制外,Java7中提供了一种新的动态调用Java程序的方法,即方法句柄MethodHandler,有些类似于C中的函数指针。此部分内容将在后续的文章中进行单独的分析。 
    展开全文
  • 权限访问的条件下,对于color和 drive()都是私有的,通过类实例是无法通过外部来访问私有变量,调用私有方法,但通过反射机制可以绕过这关限制。 package reflect.PrivateCarReflect ; import reflect....

    先看下面的小案例

    package reflect;
    
    /**
     * @Author: hegx
     * @Description:
     * @Date: 10:42 2017/7/13
     */
    public class PrivateCar {
    
        private String color;
    
        protected void drive()
        {
            System.out.println("drive private car! the color is :"+color);
        }
    }

    在权限访问的条件下,对于color和 drive()都是私有的,通过类实例是无法通过外部来访问私有变量,调用私有方法,但通过反射机制可以绕过这关限制。

    package reflect.PrivateCarReflect;
    
    import reflect.PrivateCar;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class PrivateCarReflect{
    
        public static void main(String[] args) throws Throwable{
    
           ClassLoader classLoader =  Thread.currentThread().getContextClassLoader();
           Class clazz=  classLoader.loadClass("reflect.PrivateCar");
    
            PrivateCar privateCar= (PrivateCar)clazz.newInstance();
            Field colorField = clazz.getDeclaredField("color");
    
            //权限压制  取消Java语言访问检查以访问private属性
            colorField.setAccessible(true);
            colorField.set(privateCar,"红色");
    
            Method method = clazz.getDeclaredMethod("drive",(Class[])null);
    
            method.setAccessible(true);
            method.invoke(privateCar,(Class[])null);
    
        }
    
    

    程序运行后的结构:drive private car! the color is :红色

    这跟我们当初所预测的是一样的,这就是反射的厉害之处!


    展开全文
  • Java反射机制访问类私有方法和变量

    千次阅读 2017-01-06 20:49:14
    Java反射机制访问类私有方法和变量背景利用Java的反射机制,可以得到运行时的类信息(RTTI),与传统RTTI不同的是,反射可以在运行时才得到.class文件,从而打开和检查.class文件,所有Java的反射具有很强的灵活性。...

    Java反射机制访问类私有方法和变量

    背景

    利用Java的反射机制,可以得到运行时的类信息(RTTI),与传统RTTI不同的是,反射可以在运行时才得到.class文件,从而打开和检查.class文件,所有Java的反射具有很强的灵活性。反射提供了一种机制——用来检查可用的方法,并返回方法名,当然也可用得到域变量成员等其他信息。通过反射机制获得变量的私有方法和变量理论上是可行的,而且步骤非常简单,本文将结合Java代码进行介绍。


    1. 类结构

    class Food{
        private String foodname;
    
        Food(String foodname){
            this.foodname = foodname;
        }
        private void f(){
            System.out.println("private Food Method");
        }
    }
    
    class Cake extends Food{
        private String privateCakeName;
        public String publicCakeName;
    
        Cake(String priName, String pubName, String superName){
            super(superName);
            privateCakeName = priName;
            publicCakeName = pubName;
        }
    
        private void g(){
            System.out.println("private Cake Method");
        }
    
        public void h(){
            System.out.println("public Cake Method");
        }
    }


    2. 访问本类私有变量和方法

    首先Class.getMethod(String name, Class… parameterTypes)可以得到该类以及父类可以访问到的方法,由于此处的方法为public void h(),所以可以直接通过反射得到。使用Class.getDeclaredField(String name)可以得到该类的所有方法,包括私有方法(但不能得到父类的),这样就可以通过反射调用私有方法了。注意,在调用invoke(…)之前必须加上setAccessible(boolean flag),不然会产生java.lang.IllegalAccessException,这个方法是继承自AccessibleObject类。当调用Method.setAccessible(true)后,访问控制仅对于此Method对象起作用,对于其他Method对象并不起作用。

    JDK API中的解释
    引用
        AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获得字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。
        在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。
        setAccessible 
        public void setAccessible(boolean flag) 
                           throws SecurityException 
        将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
        实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问,一般情况下,我们并不能对类的私有字段进行操作,利用反射也不例外,但有的时候,例如要序列化的时候,我们又必须有能力去处理这些字段,这时候,我们就需要调用AccessibleObject上的setAccessible()方法来允许这种访问,而由于反射类中的Field,Method和Constructor继承自AccessibleObject,因此,通过在这些类上调用setAccessible()方法,我们可以实现对这些字段的操作。但有的时候这将会成为一个安全隐患,为此,我们可以启用java.security.manager来判断程序是否具有调用setAccessible()的权限。默认情况下,内核API和扩展目录的代码具有该权限,而类路径或通过URLClassLoader加载的应用程序不拥有此权限。
    

    同样的,Class.getDeclaredFiled(String name)也可以根据name得到该类的私有域对象并访问,但是不能得到超类的域对象。

    Cake applecake = new Cake("smallAppleCake", "bigAppleCake", "cake");
    try {
        //访问本类共有方法
        Cake.class.getMethod("h").invoke(applecake);
        //Output:public Cake Method
    
        //访问本类私有方法
        Method privateMethod = Cake.class.getDeclaredMethod("g");
        privateMethod.setAccessible(true);
        privateMethod.invoke(applecake);
        //Output:private Cake Method
    
        //访问本类私有变量
        Field privateField = Cake.class.getDeclaredField("privateCakeName");
        privateField.setAccessible(true);
        System.out.println(privateField.get(applecake));
        //Output:smallAppleCake
    
    } catch (Exception e) {
        e.printStackTrace();
    }


    3.访问父类私有变量和方法

    使用Class.getSuperclass()可以得到该实体的超类,超类包括类、接口或void。得到超类后即可通过之前的方法通过反射访问超类的私有方法和私有域对象。

    Cake applecake = new Cake("smallAppleCake", "bigAppleCake", "cake");
    try {
        //访问父类私有方法
        Method privateMethod = Cake.class.getSuperclass().getDeclaredMethod("f");
        privateMethod.setAccessible(true);
        privateMethod.invoke(applecake);
        //Output:private Food Method
    
        //访问父类私有变量
        Field privateField = Cake.class.getSuperclass().getDeclaredField("foodname");
        privateField.setAccessible(true);
        System.out.println(privateField.get(applecake));
        //Output:cake
    
    } catch (Exception e) {
        e.printStackTrace();
    }


    4. 一些反射机制的应用示例

    • 得到该对象所属的类以及超类的所有域变量名(包括私有)
    private List<Field> getInheritedPrivateFields(Class<?> type) {
        List<Field> result = new ArrayList<Field>();
    
        Class<?> i = type;
        while (i != null && i != Object.class) {
            Collections.addAll(result, i.getDeclaredFields());
            i = i.getSuperclass();
        }
    
        return result;
    }
    • 改变final String 所指向的字符串内容
    final String s = "abc";
    System.out.println(s);
    //Output:abc
    Field field = s.getClass().getDeclaredField("value");
    field.setAccessible(true);
    char[] chars = (char[])field.get(s);
    chars[0] = '1';
    chars[1] = '2';
    chars[2] = '3';
    System.out.println(s);
    //Output:123


    5.有什么方法可以防止通过反射机制访问私有域和方法吗?

    SecurityManager可以限制调用setAccessible,除此之外没有其他办法。

    展开全文
  • Java反射

    2019-11-21 10:09:31
    文章目录Java反射1. 用途2. 反射相关的类Class类Field类Method类Constructor类3. 通过反射生成/操作对象生成实例对象调用方法访问成员变量值 Java反射 Java反射机制是运行状态中,对于任意一个类都能够知道这个类的...

    Java反射

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

    1. 用途

    1. 在运行时判断任意一个对象所属的类。

    2. 在运行时构造任意一个类的对象。

    3. 在运行时判断任意一个类所具有的成员变量和方法。

    4. 在运行时调用任意一个对象的方法。

    5. 生成动态代理。

    2. 反射相关的类

    类名用途
    java.lang.Class代表类
    java.lang.reflect.Field代表类的成员变量
    java.lang.reflect.Method代表类的方法
    java.lang.reflect.Constructor代表类的构造方法

    Class类

    在Java程序中获得Class对象通常有如下三种方式:

    1.使用Class类的forName(String clazzName)静态方法。该方法需要传入字符串参数,该字符串参数的值是某个类的全限定名(必须添加完整包名)。

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

    3.调用某个对象的getClass()方法。该方法是java.lang.Object类中的一个方法。

    //第一种方式 通过Class类的静态方法——forName()来实现
    class1 = Class.forName("com.mysql.jdbc.Driver");
    //第二种方式 通过类的class属性
    class1 = Person.class;
    //第三种方式 通过对象getClass方法
    Person person = new Person();
    Class<?> class1 = person.getClass();
    

    Field类

    Field[] allFields = class1.getDeclaredFields();//获取class对象的所有属性
    Field[] publicFields = class1.getFields();//获取class对象的public属性
    Field ageField = class1.getDeclaredField("age");//获取class指定属性,可以获得私有属性
    Field desField = class1.getField("des");//获取class指定的public属性
    

    Method类

    Method[] methods = class1.getDeclaredMethods();//获取class对象的所有声明方法
    Method[] allMethods = class1.getMethods();//获取class对象的所有public方法 包括父类的方法
    Method method = class1.getMethod("info", String.class);//返回次Class对象对应类的、带指定形参列表的public方法
    Method declaredMethod = class1.getDeclaredMethod("info", String.class);//返回次Class对象对应类的、带指定形参列表的方法
    

    Constructor类

    Constructor<?>[] allConstructors = class1.getDeclaredConstructors();//获取class对象的所有声明构造函数
    Constructor<?>[] publicConstructors = class1.getConstructors();//获取class对象public构造函数
    Constructor<?> constructor = class1.getDeclaredConstructor(String.class);//获取指定声明构造函数
    Constructor publicConstructor = class1.getConstructor(String.class);//获取指定声明的public构造函数
    

    3. 通过反射生成/操作对象

    生成实例对象

    1.使用Class对象的newInstance()方法来创建该Class对象对应类的实例。这种方式要求该Class对象的对应类有默认构造器,而执行newInstance()方法时实际上是利用默认构造器来创建该类的实例。

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

    //第一种方式 Class对象调用newInstance()方法生成
    Object obj = class1.newInstance();
    //第二种方式 对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成
    Constructor<?> constructor = class1.getDeclaredConstructor(String.class);//获取指定声明构造函数
    obj = constructor.newInstance("hello");
    

    调用方法

    1.通过Class对象的getMethods()方法或者getMethod()方法获得指定方法,返回Method数组或对象。

    2.调用Method对象中的Object invoke(Object obj, Object... args)方法。第一个参数对应调用该方法的实例对象,第二个参数对应该方法的参数。

     // 生成新的对象:用newInstance()方法
     Object obj = class1.newInstance();
    //首先需要获得与该方法对应的Method对象
    Method method = class1.getDeclaredMethod("setAge", int.class);
    //调用指定的函数并传递参数
    method.invoke(obj, 28);
    

    当通过Method的invoke()方法来调用对应的方法时,Java会要求程序必须有调用该方法的权限。如果程序确实需要调用某个对象的private方法,则可以先调用Method对象的如下方法。
    setAccessible(boolean flag):将Method对象的acessible设置为指定的布尔值。值为true,指示该Method在使用时应该取消Java语言的访问权限检查;值为false,则知识该Method在使用时要实施Java语言的访问权限检查。

    访问成员变量值

    1. 通过Class对象的getFields()方法或者getField()方法获得指定方法,返回Field数组或对象。

    2. Field提供了两组方法来读取或设置成员变量的值:
      第一种:getXXX(Object obj):获取obj对象的该成员变量的值。此处的XXX对应8种基本类型。
      第二种:
      在这里插入图片描述
      在这里插入图片描述

    //生成新的对象:用newInstance()方法 
    Object obj = class1.newInstance();
    //获取age成员变量
    Field field = class1.getField("age");
    //将obj对象的age的值设置为10
    field.setInt(obj, 10);
    //获取obj对象的age的值
    field.getInt(obj);
    
    展开全文
  • Java 反射

    千次阅读 2016-01-04 07:39:46
    Java 反射标签: Java基础动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如众所周知的ECMAScript(JavaScript)便是一个动态语言。除此之外如...
  • 在Android Framework隐藏了一些实用的接口,而只有使用这些接口可以完成特定功能,如:挂断电话。 本文将介绍如何利用JAVA反射机制访问ITelephony隐藏接口。
  • TestReflection3.java package study; import java.lang.reflect.Field; public class TestReflection3 { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessExcep
  • Android 6.0 动态权限 java反射

    千次阅读 2016-02-16 20:06:27
    转载请注明出处:... 一、Android 6.0 的新特性(动态权限)  将一些危险的权限在需要的时候进行询问  1.权限分组  正常(Normal Protection)权限  对
  • package com.shentb.hmb.utils; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ReflexUtils { ... * 反射根据属性名获取属性值 * * @param fieldName 属性名 * @pa...
  • java 反射

    千次阅读 2016-10-08 10:31:54
    java 反射 http://www.imooc.com/learn/199 java 反射 Class类的使用 动态加载类 获取方法信息 基本的数据类型void关键字等都存在类类型 Class类的基本API操作的 Method类提供了一些操作方法的方法 获取成员变量...
  • java反射

    千次阅读 2016-04-23 17:28:54
    java反射学习的总结,通过图示,Class的介绍、获得与运用来体现反射的内容概念。后续有代码实现与测试结果图。还有关于反射的拓展。
  • Java基础篇:反射机制详解

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

    千次阅读 多人点赞 2021-01-02 18:50:03
    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够动态调用它的任意一个方法和属性;这个动态获取信息以及动态调用对象的方法的功能称为Java语言的反射机制...
  • Java 反射机制详解

    万次阅读 多人点赞 2017-04-01 20:35:41
    为什么要写这一系列的博客呢?因为在 Android 开发的过程中, 泛型,反射,注解这些知识进场会用到,几乎所有的框架至少都会...java Type 详解java 反射机制详解注解使用入门(一)反射机制什么是反射机制简单来说,
  • Java反射有多强? 他拥有这五大神奇功能!

    万次阅读 多人点赞 2020-10-24 08:06:12
    Java反射是什么?Java反射有什么用?Java反射究竟有多方便?让我们一起见证反射的伟大吧!
  • Java 反射机制

    万次阅读 2019-10-17 17:37:24
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制...
  • Java 反射基础

    2021-06-15 20:40:42
    成员变量1、设置值2、获取值3、忽略访问权限修饰符的安全检查四、Constructor:构造方法1、创建对象:2、忽略访问权限修饰符的安全检查五、Method:方法对象1、执行方法:2、获取方法名称:六、测试需求:代码: ...
  • Java反射详解

    千次阅读 2016-07-26 11:27:32
    Java在编译时候就必须知道所引用的类所在地方,但是在实际编程中,在某些场合,可能需要引用一个并不在编译空间的类,这个时候常规方法就很难实现了。在Java中,Class配合反射能够很好的解决这种场景。
  • java反射实现类外访问类的私有成员 学习本文需要提前掌握的知识:java类与对象 1、 思路分析 想要实现访问类的私有成员,我们有两个思路,一个是将私有成员转换成公有成员,另一个思路是在访问私有成员的时候绕过...
  • 1、介绍Java反射机制和Java注解 2、利用Java反射调用类方法 3、实例讲解:自定义Java注解
  • 【Java】Java反射机制重点总结

    千次阅读 多人点赞 2020-03-07 20:00:09
    Java反射机制重点总结
  • Java反射机制学习

    千次阅读 2016-10-26 17:39:19
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 JAVA...
  • JAVA反射之取消对访问控制检查

    千次阅读 2014-02-10 11:04:08
    package test; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; ... * AccessibleObject类是Field、Method、和...它提供了将反射的对象标
  • 首先先来看一下JAVA反射的概念: JAVA反射(Reflection):在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,760
精华内容 19,104
关键字:

java反射设置访问权限

java 订阅