反思:枚举是公共的,方法也是公共的,那么为什么IlegalAccessException会出现?



请耐心等待,我尽量提供尽可能多的信息。

我得到以下异常在我的代码随机,而不是总是:

ERROR CACHE-SELECT 2015-08-20 11:19:00,822 nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'table.selectQuerySuffix'. Cause: org.apache.ibatis.ognl.OgnlException: selectQuerySuffix [java.lang.IllegalAccessException: Class org.apache.ibatis.ognl.OgnlRuntime can not access a member of class com.dclear.cmn.core.cache.CacheEnum$4 with modifiers "public"] - 

定义的Enum如下:

public enum CacheEnum {
    TABLE_NAME() {
        @Override
        public String getSelectQuerySuffix() {
            return "";
        }
    };
private CacheEnum() {
    //some assignment
}
public enum Schema {
    //SCHEMAS DEFINED
}
public enum SchemaName {
    // NAMES
}
public String getSelectQuerySuffix() {
    return "";
}
public enum ColumnEnum {
    //SOME VALUES
    ColumnEnum() {
    }
}
public enum CacheTableSequence {
    //SQs
}

}

的表。selectQuerySuffix'在MyBatis文件中定义,用于放置查询后缀。在运行时,它被传递为"(引用重写的方法getSelectQuerySuffix())

这个问题并不总是出现…我读过

当应用程序试图访问时抛出IllegalAccessException反射式地创建实例(数组除外),设置或获取字段,或调用方法,但当前执行的方法不调用是否可以访问指定的类、字段、方法的定义构造函数。

没有用户定义的类加载器

但如果问题来了,因为构造函数CacheEnum是私有的,为什么它不总是来?如果不是,那么背后的问题是什么?我遗漏了什么?

像这样定义Enum时:

public enum EnumTest {
    ONE, TWO() {
        @Override public String hello() {
            return "World";
        }
    };
    public String hello() {
        return "Hello";
    }
}
Java for TWO创建了一个匿名类。我对它进行了反汇编,它看起来像这样:
class snippet.EnumTest$1 extends snippet.EnumTest {
  snippet.EnumTest$1(java.lang.String, int);
  public java.lang.String hello();
}

所以TWOClass是包保护的,当我们实际访问TWO的类时反射不起作用。就像为TWO获取Enum对象并获取它的类。我怀疑这就是你的情况。对于方法未被覆盖的所有情况,它都在工作,对于方法被覆盖的那些情况,它应该抛出异常。

我写了下面的测试来检查它。

public class EmumReflect {
    public static void main(String[] args) throws Exception {
        f1();
        f2();
    }
    public static void f1() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException,
            InvocationTargetException {
        Class<?> forName = Class.forName("snippet.EnumTest");
        Object fOne = forName.getField("ONE").get(null);
        Object fTwo = forName.getField("TWO").get(null);
        Method method = forName.getMethod("hello");
        System.out.println(method.invoke(fOne));
        System.out.println(method.invoke(fTwo));
    }
    public static void f2() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException,
            InvocationTargetException {
        Class<?> forNamex = Class.forName("snippet.EnumTest");
        Object fTwo = forNamex.getField("TWO").get(null);
        Class<?> forName = fTwo.getClass();
        Method method = forName.getMethod("hello");
        System.out.println(method.invoke(fTwo));
    }
}

如果将类文件EnumTest和EnumReflect保存在同一个包中,则不会得到任何异常。但是,如果您将它们保存在不同的包中,则f2()会抛出与您获得的相同的异常。

相关内容

  • 没有找到相关文章

最新更新