Можно ли динамически создать класс с отражением? - PullRequest
0 голосов
/ 13 апреля 2019

Я создаю библиотеку, и в этой библиотеке она будет содержать фигуры, точнее обычные и неправильные многоугольники, эта библиотека должна позволять пользователям не только использовать мои фигуры, но и во время выполнения иметь возможность создавать свои собственные.

На данный момент у меня есть несколько фигур, представленных так:

Polygon
|- PolygonRegular
   |- Square
   |- Circle
   |- EquilateralTriangle implements Triangle
|- PolygonIrregular
   |- Trapeze
   |- IsoscelesTriangle implements Triangle

Теперь в данном сценарии, скажем, я, как пользователь, хочу создать свой собственный многоугольник, в этом случае «ScaleneTriangle», в котором также будет реализован интерфейс Triangle, моя библиотека должна легко предоставить инструменты, необходимые для создания этой «фабрики». «создавать фигуры.

  //Though I don't know the code, what I wanted to achieve, would be something very close to:

    Point2D[] points = new Point2D[]{
            new Point2D.Float(0f, 0f),
            new Point2D.Float(0.25f, 0f),
            new Point2D.Float(1f, 1f),
    };

    ContentFactory.create(PolygonIrregular.class, "ScaleneTriangle", points);

Тем не менее, я понятия не имею, как я могу создать ContentFactory, подобную этой, которая создает классы во время выполнения, как будто это было волшебство ... Я также буду волшебным образом создавать экземпляры этих классов тоже.

Чтобы дать больше понимания, если проблема не очень прояснилась: Представьте, что я пользователь, поп-холст, нарисуйте новую форму. Подтверждает. Кнопка Представление создается с этой новой формой. Каждый раз, когда пользователь нажимает кнопку buttonRepresentation, создается элемент в форме.

1 Ответ

1 голос
/ 13 апреля 2019

Есть несколько способов сделать это.

В этой статье это делается с использованием jOOQ, но вы можете повторно реализовать их метод, если не хотите дополнительной зависимости.( архив для потомков )

Способ, которым я делал это в прошлом (просто как тест), заключался в использовании компилятора из janino для компиляции строки в класс, который реализуетинтерфейс, который известен во время компиляции.Это в kotlin, но было бы легко преобразовать в Java.

package com.dmercer

import org.codehaus.janino.SimpleCompiler;
import org.codehaus.janino.util.Benchmark

fun main(args: Array<String>) {
    val sourceString = """
package com.dmercer;

public class B implements BasicInterface {
    @Override
    public void runMethod() {
        System.out.println("Hello from compiled method");
    }
}
    """.trimIndent()

    val compiler = SimpleCompiler()
    compiler.cook(sourceString)
    val classLoader = compiler.classLoader
    val compiledClass = classLoader.loadClass("com.dmercer.B")// as IDBMethod
    val classInstance = compiledClass.newInstance() as BasicInterface 
    classInstance.runMethod()

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...