代码之家  ›  专栏  ›  技术社区  ›  zapatilla

从Jython访问受保护的Java属性

  •  1
  • zapatilla  · 技术社区  · 6 年前

    我正在使用Java Swing用Jython构建一个文本编辑器。我遇到了 CompoundEdit ,一个Swing类,其中包含来自文本编辑器的编辑操作列表。这个属性是受保护的,这意味着我不能直接从另一个类访问它,但我可以从扩展它的其他类访问它。所以,如果我创建一个 MyEdit 扩展的类 CompoundEdit , MyEdit公司 应该有权访问编辑列表。

    这就是我想要的:

    class MyEdit(CompoundEdit):
        def __init__(self):
            super(CompoundEdit, self).__init__()
            print(dir(self)) # Doesn't show the edits
            self.nammu_edits = super(CompoundEdit, self).edits 
    

    运行此命令会出现以下错误:

    AttributeError: 'super' object has no attribute 'edits'
    

    作为参考,这是 dir 回来时:

    ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__initProxy__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__supernames__', '__unicode__', '__weakref__', '_getPyInstance', '_getPySystemState', '_setPyInstance', '_setPySystemState', 'addEdit', 'canRedo', 'canUndo', 'class', 'classDictInit', 'clone', 'die', 'doPrint', 'end', 'equals', 'finalize', 'getClass', 'getPresentationName', 'getRedoPresentationName', 'getUndoPresentationName', 'hashCode', 'inProgress', 'isInProgress', 'isSignificant', 'lastEdit', 'notify', 'notifyAll', 'presentationName', 'redo', 'redoPresentationName', 'replaceEdit', 'significant', 'toString', 'undo', 'undoPresentationName', 'wait']
    

    这是CompoundEdit.java代码的摘录:

    public class CompoundEdit extends AbstractUndoableEdit {
        /**
         * True if this edit has never received <code>end.
         */
        boolean inProgress;
    
        /**
         * The collection of <code>UndoableEdits
         * undone/redone en masse by this <code>CompoundEdit.
         */
        protected Vector<UndoableEdit> edits;
    
        public CompoundEdit() {
            super();
            inProgress = true;
            edits = new Vector<UndoableEdit>();
        }
    

    我在Java中也尝试过同样的方法,它允许我访问 edits . Jython版本有什么地方我做错了吗?Jython中是否有访问受保护变量的特殊方法?在文档中提到了一些关于调用 super__<method>() ,但我试过这个案子,也没用。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Alex    6 年前

    @mzjn是正确的。设置 python.security.respectJavaAccessibility = false 是从子类访问受保护字段的唯一方法。这是因为 org.python.core.PyJavaType.init(Class<?>, Set<PyJavaType>) :

    // Add fields declared on this type
    Field[] fields;
    if (Options.respectJavaAccessibility) {
        // returns just the public fields
        fields = forClass.getFields();
    } else {
        fields = forClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }
    }
    

    但是,你 可以 不设置就调用受保护的方法 respectJavaAccessibility false ,因为方法查找使用不同的算法。我发现这是一个错误,我没有找到任何提到,这是故意的行为。

    或者只使用Java反射获取受保护字段值:

    class MyEdit(CompoundEdit):
        #...
        def get_edits(self):
            edits_field = CompoundEdit.getDeclaredField('edits')
            edits_field.setAccessible(True)
            return edits_field.get(self)