Чтобы понять это, вам нужно понять, как на самом деле работают классы и загрузка классов в Java. Часто мы думаем о загрузке с точки зрения «пути к классам», но это сильно упрощает то, как все работает. Во многих средах Java SE это просто работает, но в средах с несколькими арендаторами, таких как OSGi, все становится сложнее.
По сути, классы Java ограничены тремя вещами:
- Имя
- Упаковка
- ClassLoader
Вполне возможно, что два экземпляра myPackage.MyClass будут загружены в JVM более одного раза, вам просто нужно несколько загрузчиков классов. Несмотря на то, что эти классы могут быть загружены из идентичных файлов .class, они будут отличаться во время выполнения. Это может вызвать много путаницы, когда вы пишете такой код:
MyClass c = (MyClass)obj;
и получить ClassNotFoundException: MyClass
.
Классы существуют в пакетах, и с этим связаны специальные правила видимости. Типы, методы и поля, для которых не указана видимость, видны всем типам в одном пакете. Когда класс загружается, он связывается с java.lang.reflect.Package, и правила видимости разрешаются путем проверки того, что классы связаны с одним и тем же экземпляром java.lang.reflect.Package. Таким образом, в случае mypackage.MyClass, если вы загрузите его дважды, используя два разных загрузчика классов, вы получите два экземпляра Package для mypackage.
OSGi разработан для поддержки загрузки классов с несколькими арендаторами, это то, что позволяет вам одновременно иметь две разные версии класса или пакета в одной и той же JVM. Это решает многие проблемы, возникающие, если у вас разные зависимости от версии. Он реализует это, используя разные загрузчики классов для каждого пакета. Фрагменты работают иначе, чем пакеты, поскольку они связаны с пакетом, а классы в них загружаются загрузчиком классов пакета, а не собственным.
Чтобы связать это с вашим первоначальным вопросом, если вы поместите свои тесты junit в пакет (а не во фрагмент), ваш класс будет загружен другим загрузчиком классов, поэтому он будет связан с другим экземпляром java.lang.reflect. Упакуйте так, чтобы когда JVM тестировала доступность члена, она не удалась.
person
Alasdair
schedule
11.06.2015