Как прочитать значение частного поля из другого класса в Java?

Я хотел бы добавить, что если вы получите расширение MoreLinq, теперь есть поддержка как гомогенных, так и гетерогенных левых соединений теперь

http://morelinq.github.io/2.8/ref /api/html/Overload_MoreLinq_MoreEnumerable_LeftJoin.htm

пример:

//Pretend a ClientCompany object and an Employee object both have a ClientCompanyID key on them

return DataContext.ClientCompany
    .LeftJoin(DataContext.Employees,                         //Table being joined
        company => company.ClientCompanyID,                  //First key
        employee => employee.ClientCompanyID,                //Second Key
        company => new {company, employee = (Employee)null}, //Result selector when there isn't a match
        (company, employee) => new { company, employee });   //Result selector when there is a match

EDIT:

В ретроспективе это может сработать, но оно преобразует IQueryable для IEnumerable, поскольку morelinq не преобразует запрос в SQL.

Вместо этого вы можете использовать GroupJoin, как описано здесь: https://stackoverflow.com/a/24273804/4251433

Это гарантирует, что он останется как IQueryable, если вам понадобится дальнейшие логические операции над ним позже.

459
задан Steve Chambers 23 January 2018 в 13:51
поделиться

5 ответов

Чтобы получить доступ к закрытым полям, вам необходимо получить их из объявленных полей класса, а затем сделать их доступными:

Field f = obj.getClass().getDeclaredField("stuffIWant"); //NoSuchFieldException
f.setAccessible(true);
Hashtable iWantThis = (Hashtable) f.get(obj); //IllegalAccessException

РЕДАКТИРОВАТЬ : как было прокомментировано aperkins , оба доступа к полю, установка его как доступного и получение значения все вызовут Exception , хотя единственное ] проверено исключения, о которых необходимо помнить, прокомментированы выше.

NoSuchFieldException будет сгенерировано, если вы запросите поле по имени, которое не соответствует объявленному полю.

obj.getClass().getDeclaredField("misspelled"); //will throw NoSuchFieldException

Исключение IllegalAccessException было бы сгенерировано, если бы поле было недоступно (например, если оно было закрытым и не было сделано доступным из-за отсутствия f.setAccessible (true) строка.

RuntimeException , которые могут быть сгенерированы, либо SecurityException s (если JVM's SecurityManager не позволит вам изменить доступность поля), или IllegalArgumentException s, если вы попытаетесь получить доступ к полю на объекте, не относящемся к типу класса поля:

f.get("BOB"); //will throw IllegalArgumentException, as String is of the wrong type
648
ответ дан 22 November 2019 в 22:54
поделиться

Отражение - не единственный способ решить вашу проблему (который заключается в доступе к частным функциям / поведению класса / компонента)

Альтернативным решением является извлечение класса из .jar, декомпилируйте его с помощью (скажем) Jode или Jad , измените поле (или добавьте метод доступа) и перекомпилируйте его с исходным .jar. Затем поместите новый .class перед .jar в пути к классам или повторно вставьте его в .jar . (утилита jar позволяет извлекать и повторно вставлять в существующий .jar)

Как указано ниже, это решает более широкую проблему доступа / изменения частного состояния, а не просто доступа / изменения поля.

Для этого требуется .jar , конечно, не подписывать.

26
ответ дан 22 November 2019 в 22:54
поделиться

Как упоминает oxbow_lakes, вы можете использовать отражение, чтобы обойти ограничения доступа (при условии, что ваш SecurityManager позволит вам).

Тем не менее, если этот класс настолько плохо спроектирован, что он заставляет вас прибегая к такому взлому, может стоит поискать альтернативу. Конечно, эта небольшая хитрость может сэкономить вам несколько часов, но сколько это будет стоить вам в будущем?

5
ответ дан 22 November 2019 в 22:54
поделиться

Используйте a.splitlines () . Появится список отдельных строк. Чтобы получить результат «должно быть», добавьте «». join (a.splitlines ()) , и чтобы получить все в нижнем регистре, как показано, вся энчилада выглядит как «». join (a.splitlines ()) .lower () .

-121--1881258-

В параметре OutputCacheAttribute необходимо также указать параметр OxerParam . В противном случае это исключение будет получено при обработке результатов System.Web. Можно попытаться добавить этот параметр и проверить, работает ли он.

-121--2711755-

Используйте рамку Soot Java Optimization для непосредственного изменения байт-кода. http://www.sable.mcgill.ca/soot/

Суда полностью написана на Java и работает с новыми версиями Java.

4
ответ дан 22 November 2019 в 22:54
поделиться

Один другой вариант, который еще не упомянул: используйте Groovy . Groovy позволяет получить доступ к частным переменным экземпляра в качестве побочного эффекта конструкции языка. Есть ли у вас добыча для поля, вы можете просто использовать

def obj = new IWasDesignedPoorly()
def hashTable = obj.getStuffIWant()
18
ответ дан 22 November 2019 в 22:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: