从Jython访问受保护的Java属性

时间:2018-10-15 19:28:11

标签: java swing jython

我正在使用Java Swing与Jython构建文本编辑器。我遇到过CompoundEdit,这是一个Swing类,其中包含来自文本编辑器的编辑操作列表。这个属性是受保护的,这意味着我不能直接从另一个类访问它,但是可以从其他扩展它的类中访问它。因此,如果我创建一个扩展了MyEdit的{​​{1}}类,则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

这是CompoundEdit.java代码的一部分:

['__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']

我从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>(); } 。在Jython版本中我做错什么了吗? Jython中是否有一种特殊的方法来访问受保护的变量?在文档中,它提到了有关调用edits的内容,但是在这种情况下我尝试了它,但它也不起作用。

1 个答案:

答案 0 :(得分:1)

@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,因为方法查找使用了不同的算法。 IMO,这是一个错误,我找不到任何提及此行为的意图。

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

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