Путаница с classesInOtherPkgWithProtectedMember в JVM spe c и, в более общем плане, правилами доступа к защищенному члену - PullRequest
0 голосов
/ 11 января 2020

Состояние Java jvms :

Предикат classesInOtherPkgWithProtectedMember (Class, MemberName, MemberDescriptor, MemberClassName, Chain, List) имеет значение true, если List является набором классов в цепочке с именем MemberClassName, которые находятся в другом пакете времени выполнения, чем класс, в котором есть защищенный член с именем MemberName с дескриптором MemberDescriptor.

classesInOtherPkgWithProtectedMember(_, _, _, _, [], []).

classesInOtherPkgWithProtectedMember(Class, MemberName,
    MemberDescriptor, MemberClassName,
    [class(MemberClassName, L) | Tail],
    [class(MemberClassName, L) | T]) :-
    differentRuntimePackage(Class, class(MemberClassName, L)),
    loadedClass(MemberClassName, L, Super),
    isProtected(Super, MemberName, MemberDescriptor),
    classesInOtherPkgWithProtectedMember(
    Class, MemberName, MemberDescriptor, MemberClassName, Tail, T).

classesInOtherPkgWithProtectedMember(Class, MemberName,
    MemberDescriptor, MemberClassName,
    [class(MemberClassName, L) | Tail],T) :-
    differentRuntimePackage(Class, class(MemberClassName, L)),
    loadedClass(MemberClassName, L, Super),
    isNotProtected(Super, MemberName, MemberDescriptor),
    classesInOtherPkgWithProtectedMember(
    Class, MemberName, MemberDescriptor, MemberClassName, Tail, T).

classesInOtherPkgWithProtectedMember(Class, MemberName,
                                    MemberDescriptor, MemberClassName,
                                    [class(MemberClassName, L) | Tail],
                                    T) :-
    sameRuntimePackage(Class, class(MemberClassName, L)),
    classesInOtherPkgWithProtectedMember(
    Class, MemberName, MemberDescriptor, MemberClassName, Tail, T).

Однако, глядя на определение classesInOtherPkgWithProtectedMember (выше ), мы видим, что определения classesInOtherPkgWithProtectedMember всегда выводят class(MemberClassName, L) из Цепи. Учитывая простую цепочку суперкласса, такую ​​как ниже, classesInOtherPkgWithProtectedMember всегда завершится ошибкой, поскольку не может получить класс с одинаковым именем для каждого элемента цепочки. Точнее говоря, он вынужден всегда вызывать класс с именем MemberClassName.

    class('java/util/HashMap',bootstrapLoader)
    class('java/util/AbstractMap',bootstrapLoader),
    class('java/lang/Object',bootstrapLoader)

. Я неправильно интерпретирую этот код Пролога, или classesInOtherPkgWithProtectedMember не удается для всех нетривиальных значений Chain? Это как-то полагается на возврат, чтобы получить более простой Chain, который затем может быть успешным? Существует ли какая-то гибкая концепция имени, где иногда MemberClassName относится к неквалифицированному имени, а иногда относится к имени + пакет? Должны ли быть MemberClassName1 и MemberCLassName2, чтобы один и тот же класс не выталкивался из цепочки каждый раз?

...