ClassLoader - что это такое?

  • 32
  • Недоступна
Реализуй логику метода getAllAnimals. Аргумент метода pathToAnimals - это абсолютный путь к директории, в которой хранятся скомпилированные классы. Путь не обязательно содержит / в конце. НЕ все классы наследуются от интерфейса Animal. НЕ все классы имеют публичный конструктор без параметров. Только
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (113)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Edil Kalmamatov
Уровень 35
26 сентября, 22:49
Не стал заморачиваться с проверкой поддержки загруженным классом интерфейса Animal, а просто сделал вставку экземпляра класса в список через try-catch с пустыми блоками catch. Валидатор принял.
Ян
Уровень 36, Лида, Беларусь
13 ноября, 12:24
Подскажите, пожалуйста, какой смысл в методе main() и в возвращаемом типе метода getAllAnimals() писать
Set<? extends Animal>
если в методе getAllAnimals(), мы всё равно жёстко задаём Set с типом-параметром Animal (т.е. Set<Animal>), наполняем его и возвращаем? Разве не проще тогда сразу везде написать
Set<Animal>
ведь свои реализации методов каждого потомка класса Animal, по-любому утратятся?
Николай Т.
Уровень 40, Рязань, Россия
21 июля, 18:20
Прочитал ссылки, комментарии. Сначала тыкался с URLClassLoader. Но так и не нашёл способа чтобы он по имени или абсолютному пути загружал класс. Потом нашёл реализацию Calssloader и сделал по аналогии переопределив метод findClass. Полностью не разобрался в теме, гуглил много но что-то выдавало всё не то :(
Maks Panteleev Java Developer в Bell Integrator
20 июля, 10:41
Задача успешно прошла тестирование! Да детка!) прочитал кучу материала, пересмотрел кучу видосов и перечитал кучу комментов, но все таки справился) Тут почему то пишут что переопределять надо метод loadClass, но так ничего не работает. Я переопределял findClass и тогда все заработало. А сам алгоритм довольно простой - любым известным способом итерируемся по папке и для каждого файла делаем такую штуку -
Class clazz = НашНаследникClassLoader.loadClass(абсолютный путь до файла);
это дефолтный метод класслоадера, а он уже в свою очередь сам вызывает файндкласс, который мы переопределили, а сделали это тоже просто - вычитали из переданного пути массив байт и вернули
defineClass(null, bytes, 0, bytes.length);
А дальше уже получаем у класса интерфейсы, в иф блоке ищем анимал, у него пробуем запросить пустой конструктор и если получается, добавляем в сет. Все достаточно просто, но чтоб разобраться потребовалось изучить очень много материала))
Ян
Уровень 36, Лида, Беларусь
13 ноября, 12:27
Подскажите, пожалуйста, какой смысл в методе main() и в возвращаемом типе метода getAllAnimals() писать
Set<? extends Animal>
если в методе getAllAnimals(), мы всё равно жёстко задаём Set с типом-параметром Animal (т.е. Set<Animal>), наполняем его и возвращаем? Разве не проще тогда сразу везде написать
Set<Animal>
ведь свои реализации методов каждого потомка класса Animal, по-любому утратятся?
Igor
Уровень 41, Минск, Беларусь
27 июня, 15:02
Если Валя не принимает ваше решение, но из трёх классов:
Cat
Elephant
Sheep
У вас решение такое, т.е. только один класс: [com.javarush.task.task35.task3507.data.Cat@66d3c617] То задача решена.😒 Пример моего костыльного решения: 1. Создал директорию по пути (pathToAnimals); 2. Пройтись по каждому файлу. 2.1 Если файл это .class, то создаём ClassLoader, в котором загрузим в массив байтов файл и создадим загрузчик класса, чтобы потом его создать.
...
byte[] classBytes = Files.readAllBytes(file.toPath());
... defineClass(null, classBytes, 0, classBytes.length);
...
2.2 Создаём класс с именем
String classSimpleName = file.getName().replace(".class", "");
Class<?> clazz = loader.loadClass(classSimpleName);
2.2 Добавляем объект в множество:
... (Animal) clazz.newInstance());
15 строчек всего, а слов то было...
Edil Kalmamatov
Уровень 35
26 сентября, 22:37
каким образом исполняется команда
byte[] classBytes = Files.readAllBytes(file.toPath());
если вы подаете только имя файла без пути, еще и удаляете расширение файла?
Булат
Уровень 37, Москва
9 мая, 16:55
чето какая-то слишком дичь
Flexo Bending Unit #3370318
17 апреля, 17:27
Читаю все комментарии после долгих корпений над классом ClassLoader... Что можно сказать — всем нужно пройти через одни и те же грабли, причём грабли не собственные, а заботливо подложенные JR Вообще говоря, всё верное решение занимает около 15 строк кода внутри метода, но оно, конечно же, не принимается (по первым двум пунктам) Кому-то может быть полезно: вот так работает вызов загрузки класса по умолчанию:
String binaryName = packageStr + "." + file.replace(".class", "");
Class clazz = Class.forName(binaryName);
file - имя бинарного(скомпилированного) файла класса вида "Cat.class" binaryName - "бинарное имя класса", в документации Джавы это имена классов вида
"java.lang.String"
"javax.swing.JSpinner$DefaultEditor"
"java.security.KeyStore$Builder$FileBuilder$1"
"java.net.URLClassLoader$3$1"
Что хочет видеть валидатор в вашем коде: Вы должны создать и использовать такую реализацию загрузчика, которая бы работала с параметром (String classSimpleName), где classSimpleName - простое имя класса, такое как "Cat" или "Dog".
String classSimpleName = file.replace(".class", "")
Class clazz = loader.loadClass(classSimpleName);
А как загрузчик должен узнать полный путь к файлу или бинарное имя класса из одного только простого имени, спросите вы – а никак! Я, например, передавал путь в конструктор загрузчика при создании экземпляра (самописный конструктор с параметром в виде полного пути - костыли, это по-нашему). И ещё, из озарений:
return defineClass(null, b, 0, b.length);
глаза лезут на лоб, и в голове крутится только один вопрос "а что, так можно было??" в смысле, подставлять нуль вместо имени. а если не нуль и не совпадает с бинарным, то вот тебе NoClassDefFoundError!
Igor
Уровень 41, Минск, Беларусь
27 июня, 15:04
Должно быть не:
String classSimpleName = file.replace(".class", "");
а вот так
String classSimpleName = file.getName.replace(".class", "");
🤓 Про бинарное имя класса - спасибо!👍
Alexey
Уровень 36, Россия
15 апреля, 13:26
Если кому-то пригодится. Решил задачу сначала через ClassLoader.getSystemClassLoader() + костыли с получением полного имени класса. Все как по условию задачи. Но почему-то 1 и 2 ой пункт не принялись Если я правильно понимаю, почему-то валидатору хочется, чтобы всё было через defineClass Поэтому погуглив и почитав статейки я переделал под defineClass. И принялось.
tremb
Уровень 37, Москва, Россия
7 апреля, 21:08
Решение дает верный ответ: один класс. Проверяется File[] files, проверяется каждый отдельный file : не директория, заканчивается на .class. загрузка : MyClassLoader extends ClassLoader, super.loadClass(name) Но 1 и 2 пункты не проходят проверку. И почему то проходят 3, 4 пока бросил.
tremb
Уровень 37, Москва, Россия
7 апреля, 21:57
2975 АБЗАЦ!!! Вы решили задачу лучше, чем 1% учеников. Вам удалось ее решить с 12 попытки. Среднее количество попыток для этой задачи 2.2. Всего эту задачу решили 2975 учеников.🤣 :🤣🤣 1 2 Пункты не причем! Читаем http://java-online.ru/java-classloader.xhtml. Всё встаёт на место. Пробуем: Class<?> clazz = Class.forName(className); className – the fully qualified name of the desired class. className = Solution.class.getPackage().getName() + ".data." + file.getName().replace(".class", ""); И всё! Так и будете делать по жизни! Вся задача решается одной строкой! Последующая фильтрация - сермяга. НО НЕТ!! Валику нужно создать свой класс и метод, который вызывает читает содержимое файла и вызывает defineClass(className, b, 0, b.length); (className можно заменить на null).
Maksim Mikhailovskiy
Уровень 37, Украина
7 апреля, 10:55
Фух с 14й попытки. У меня не принимал потому что я в этой строчкке
return defineClass(null, bytes, 0, bytes.length);
вместо null передовал полное имя скласса (com.javarush...) Валя хочет null
tbcarus
Уровень 41, Москва
19 марта, 22:59
Сама задача не сложная, довольно быстро приходит понимание, где почитать и какие пару методов использовать и класс ранее не использовавшиеся применить. А вот валидатор тут совсем не прост, бодаться с ним за правильность решения я не стал.