java.lang.IllegalAccessException:与类的public / private属性有关吗?

时间:2011-02-24 13:29:28

标签: java exception

我的Java代码中出现以下错误:

java.lang.IllegalAccessException: Class org.apache.commons.digester.ObjectCreateRule can not access a member of class Response with modifiers ""

可能是因为课程响应不是公共课吗? 如果是这样,我怎样才能使它可访问并将类Response保存在与主类相同的文件中?

感谢

更新,代码:http://www.smipple.net/snippet/aneuryzma/on:%20is%20related%20to%20public%20/%20private%20attribute%20for%20classes%20%3F

4 个答案:

答案 0 :(得分:8)

据我记得你的类响应应该遵循bean约定:应该是public,应该有公共默认构造函数,并且应该有你从xml引用的所有字段的setter和getter。

答案 1 :(得分:4)

是的,正如IllegalAccessException documentation所说的那样。

您可以使用反射绕过访问修饰符。例如,要访问私有字段,请使用Class.getDeclaredField(String)获取特定的Field(也适用于私有字段 - 使用普通getField只能获取公共成员),然后设置{{1 }}。现在,该字段可以像公开一样使用。

您还可以使用JNI规避访问修饰符。它根本不关心访问修饰符。还有一种方法是使用ASM等工具生成自定义字节码。

答案 2 :(得分:1)

  

无法使用修饰符“”

访问“响应”类的成员

成员是一个实例变量,修饰符为publicprotectedstatic,...

所以在我看来,Response类有一个无法通过apache-commons-digesters ObjectCreationRule访问或创建的字段。

您有一个Response类与digester不兼容,或者错误位于定义Response类的xml文件中。


查看代码 - 没有访问修饰符的唯一Java“项”是类ResponseRequest。也许错误告诉我们这些课程必须公开。

答案 3 :(得分:0)

ObjectCreateRule尝试通过它的类名使用加载请求,然后调用Class.newInstance()。要使其工作,请求和响应都需要public并具有公共默认构造函数。

您有两种选择:  1.将请求和响应放在他们自己的源文件中并公开  2.在您的公共顶级课程中嵌套请求和响应,并将其设为public static

如果您选择了选项2,那么您的代码将如下所示:     import java.io.Reader;     import java.io.StringReader;

import org.apache.commons.digester.Digester;

public class DigExample {

    public static void main(String ar[]) {
        try {
            Digester digester = new Digester();
            digester.setValidating( false );

            digester.addObjectCreate( "response", Response.class );

            digester.addObjectCreate( "response/request", Request.class );
            digester.addBeanPropertySetter("response/request/name", "name" );
            digester.addBeanPropertySetter("response/request/value", "value" );
            digester.addSetNext( "response/request", "setRequest" );

            digester.addBeanPropertySetter( "response/matches", "matches" );

            Reader reader = new StringReader(
                            "<?xml version='1.0' encoding='UTF-8'?>" + 
                            "<response>" + 
                            "<request><name>books</name><value>xml</value></request>" +  
                            "<matches>20</matches>" + 
            "</response>");
            Response response = (Response)digester.parse( reader );

            System.out.println( response.toString() );

        } catch( Exception exc ) {
            exc.printStackTrace();
        }

    }
    static  public  class Response {

        public Response(){}

        private int _matches = 0;
        private Request  _request;

        public Request getRequest() {
            return _request;
        }

        public void setRequest(Request request) {
            _request = request;
        }

        public int getMatches() {
            return _matches;
        }

        public void setMatches(int matches) {
            _matches = matches;
        }

    }



    static public class Request {

        public Request() {}

        private String _name = "";
        private String _value = "";

        public String getName() {
            return _name;
        }

        public void setName(String name) {
            _name = name;
        }

        public String getValue() {
            return _value;
        }

        public void setValue(String value) {
            _value = value;
        }

    }
}

正如其他人所提到的,如果您直接使用反射,则可能会绕过访问修饰符,但这不是您示例中的选项。