Обычно загрузчики классов используются для изоляции JAR. Если у вас есть приложение, использующее подключаемые модули (Eclipse, Maven 2), то у вас может быть такая ситуация: плагину X требуется jar A версии 1.0, а плагину Y нужен тот же jar, но версии 2.0. Однако X не работает с версией 2.0.
Если у вас есть загрузчики классов, вы можете создавать разделы классов (подумайте об изолированных островах, соединенных тонкими мостами; мосты — это загрузчики классов). Таким образом, загрузчики классов могут контролировать то, что может видеть каждый плагин.
Когда плагин X создает экземпляр класса Foo, который имеет статические поля, это не проблема, и не будет путаницы с «тем же самым» классом в плагине Y, потому что каждый загрузчик классов фактически создаст свой собственный экземпляр класса Foo. Затем у вас есть два класса в памяти, где cl1.getName().equals(cl2.getName())
равен true
, а cl1.equals(cl2)
— нет. Это означает, что экземпляры cl1 несовместимы по присваиванию с экземплярами cl2. Это может привести к странным ClassCastExceptions
, которые говорят, что org.project.Foo
не может быть назначено org.project.Foo
.
Как и в случае с удаленными островами, два класса не знают о существовании другого. Подумайте о человеческих клонах, которые рождаются, а затем вырастают на разных островах. С точки зрения ВМ проблем нет, потому что экземпляры типа Class обрабатываются как любой другой объект: их может быть несколько. То, что вы думаете, что некоторые из них «одинаковые», не имеет значения для ВМ.
Другое использование этого шаблона заключается в том, что вы можете избавиться от классов, загруженных таким образом: просто убедитесь, что ни у кого нет указателя на какой-либо объект, созданный из классов, загруженных из загрузчика классов, а затем забудьте о загрузчике классов. При следующем запуске GC все классы, загруженные этим загрузчиком классов, удаляются из памяти. . Это позволяет вам «перезагрузить» ваше приложение без перезапуска всей виртуальной машины.
person
Aaron Digulla
schedule
12.02.2009