Skip to content

Instantly share code, notes, and snippets.

@fermopili
Created May 19, 2017 12:03
Show Gist options
  • Save fermopili/1be4f8242c50f9b129b2b5c2c0e375ac to your computer and use it in GitHub Desktop.
Save fermopili/1be4f8242c50f9b129b2b5c2c0e375ac to your computer and use it in GitHub Desktop.
com.javarush.task.task36.task3606 Осваиваем ClassLoader и Reflection
package com.javarush.task.task36.task3606.data.second;
import com.javarush.task.task36.task3606.HiddenClass;
public class HiddenClassImplFirst implements HiddenClass {
}
package com.javarush.task.task36.task3606.data.second;
import com.javarush.task.task36.task3606.HiddenClass;
public class HiddenClassImplSecond implements HiddenClass {
private HiddenClassImplSecond() {
}
}
package com.javarush.task.task36.task3606.data.second;
import com.javarush.task.task36.task3606.HiddenClass;
class PackageAccessClass implements HiddenClass {
PackageAccessClass() {
}
}
package com.javarush.task.task36.task3606;
public interface HiddenClass {
}
package com.javarush.task.task36.task3606;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
/*
Осваиваем ClassLoader и Reflection
*/
public class Solution
{
private List<Class> hiddenClasses = new ArrayList<> ( );
private String packageName;
public Solution(String packageName)
{
this.packageName = packageName;
}
public static void main(String[] args) throws ClassNotFoundException
{
Solution solution = new Solution ( Solution.class.getProtectionDomain ( ).getCodeSource ( ).getLocation ( ).getPath ( ) + "com/javarush/task/task36/task3606/data/second" );
solution.scanFileSystem ( );
System.out.println ( solution.getHiddenClassObjectByKey ( "hiddenclassimplse" ) );
System.out.println ( solution.getHiddenClassObjectByKey ( "hiddenclassimplf" ) );
System.out.println ( solution.getHiddenClassObjectByKey ( "packa" ) );
}
public void scanFileSystem() throws ClassNotFoundException
{
File[] files = new File ( packageName ).listFiles ( );
ClassLoaderFromPath classLoader = new ClassLoaderFromPath ( );
for (File f : files)
{
Class<?> clazz = classLoader.load ( f.toPath ( ) );
if (clazz != null)
hiddenClasses.add ( clazz );
}
}
public HiddenClass getHiddenClassObjectByKey(String key)
{
for (Class<?> clazz : hiddenClasses)
{
if (clazz.getSimpleName ( ).toLowerCase ( ).startsWith ( key.toLowerCase ( ) ))
{
try
{
Constructor[] constructors = clazz.getDeclaredConstructors ( );
for (Constructor constructor : constructors)
{
if (constructor.getParameterTypes ( ).length == 0)
{
constructor.setAccessible ( true );
return (HiddenClass) constructor.newInstance ( null );
}
}
}
catch (Exception e)
{
return null;
}
}
}
return null;
}
public static class ClassLoaderFromPath extends ClassLoader
{
public Class<?> load(Path path)
{
try
{
if (path.getFileName ( ).toString ( ).lastIndexOf ( ".class" ) == -1)
return null;
byte[] b = Files.readAllBytes ( path );
return defineClass ( null, b, 0, b.length ); //here main magic
}
catch (IOException e)
{
e.printStackTrace ( );
}
return null;
}
}
}
taskKey="com.javarush.task.task36.task3606"
Осваиваем ClassLoader и Reflection
Аргументом для класса Solution является абсолютный путь к пакету.
Имя пакета может содержать File.separator.
В этом пакете кроме скомпилированных классов (.class) могут находиться и другие файлы (например: .java).
Известно, что каждый класс имеет конструктор без параметров и реализует интерфейс HiddenClass.
Считай все классы с файловой системы, создай фабрику - реализуй метод getHiddenClassObjectByKey.
Примечание: в пакете может быть только один класс, простое имя которого начинается с String key без учета регистра.
Требования:
1. Реализуй метод scanFileSystem, он должен добавлять в поле hiddenClasses найденные классы.
2. Реализуй метод getHiddenClassObjectByKey, он должен создавать объект класса согласно условию задачи.
3. Метод main не изменяй.
4. Метод getHiddenClassObjectByKey не должен кидать исключений.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment