как создать файл java программно

Я создаю служебный класс, который пишет .java Files, который действует как укрыватель-генератор.

Этот служебный класс создаст AConverter.java' (см. пример ниже)

Я хочу знать, как написать служебный класс.
Я погуглил и нашел рекомендацию использовать apache bcel. Но я не смог найти пример написания .java File из String и заставить его работать в моей программе.



Ожидание...

class ADTO
{
    private String empId;
    private String empName;
    private String dept;

    //setters and getters
}

class ABO
{
    private String loginId;
    private String userName;
    private String group;

    //setter and getter
}

class AConverter
{
    public void doConvertFromDB(ADTO source, ABO dest)
    {
        dest.setLoginId(source.getEmpId());
        ...
    }

    public void doConvertFromBO(ABO source, ADTO dest)
    {
        dest.setEmpId(source.getLoginId());
        ...

    public ADTO getSourceClass()
    {
        return ADTO.class;
    }

    public ABO getDestClass()
    {
        return ABO.class;
    }
}

Приведенный выше класс AConverter будет сгенерирован новым Util-классом.


person VAm    schedule 01.08.2012    source источник
comment
Большинство инструментов используют для создания файлов .class, а не исходного кода Java.   -  person Peter Lawrey    schedule 01.08.2012
comment
Я переписал ваш вопрос, чтобы лучше объяснить, что вам нужно. Я правильно понял?   -  person Angelo Fuchs    schedule 01.08.2012
comment
@AngeloNeuschitzer: я добавил то, что именно требуется в классе Util. Это имеет смысл?   -  person VAm    schedule 01.08.2012
comment
@VAm Я придерживаюсь своего ответа, проблема сложнее, чем этот сайт может решить. Делать то, что вы хотите, не просто и не быстро. Используйте BCEL (создает файлы .class) или APT (может использоваться для создания файлов .java) или какую-либо другую библиотеку, если вам это нужно. (Я бы сделал это с помощью APT.)   -  person Angelo Fuchs    schedule 01.08.2012


Ответы (2)


Вы почти наверняка выиграете, если попытаетесь сделать это по-другому, количество способов, которыми эта схема может потерпеть неудачу, тревожно велико. Вот несколько предложений:

  1. Добавьте какой-нибудь метод заклинателя:

    class ADTO
    {
        private String empId;
        private String empName;
        private String dept;
    
        // setters and getters
    
        public ABO toABO() // caster method (ABO will need a toADTO() as well)
        {
            ABO a = new ABO();
    
            a.setSomething(getSomethingEquivalent());
            ...
    
            return a;
        }
    }
    
  2. Прокси-класс, возможно, подкласс предполагаемого класса. Вам понадобится 2, по одному производному от каждого класса.

    class ADTO_Proxy extends ADTO
    {
        private ABO abo;
    
        public ADTO_Proxy(ABO a)
        {
            super();
            abo = a;
        }
    
        @override
        public String getEmployeeId()
        {
            return abo.getLoginId();
        }
    
        // other setters and getters
    }
    
  3. Вместо того, чтобы пытаться сделать адаптер, объедините классы. Может быть легко выполнено с помощью следующего:

    class ADTO
    {
        private String empId;
        private String empName;
        private String dept;
    
        // getters and setters for each variable by each name
        public String getEmployeeId()
        { return empId; }
        public String getLoginId()
        { return empId; }
    
        public String getEmployeeName()
        { return empName; }
        public String getUsername()
        { return empName; }
    
        public String getDepartment()
        { return dept; }
        public String getGroup()
        { return dept; }
    
        // setters
    }
    

    Это также можно сделать с помощью интерфейсов.

Рейтинги HateYourselfLater™:

Первый метод оценивается как 2, лучший из трех. Оценка заработана, потому что вы никогда не обнаружите, что случайно переключаетесь между ними, и не нужно менять много другого кода.

Второй метод занимает -3, в середине из трех. Оценка заработана, потому что вы можете иногда смешивать объекты одного типа с другими, что может привести к непреднамеренным побочным эффектам. Вы можете уменьшить это значение до 0, если исключите сеттеры из прокси-классов, но это ограничивает функциональность.

Третий метод получает -5, худший из трех. Оценка заработана, потому что есть много возможностей для побочных эффектов, а избыточный код, вероятно, позже сбьет вас с толку. Тем не менее, вы можете получить рейтинг 1, рефакторинг всего, чтобы правильно использовать только один класс, но это может потребовать много работы, и вы будете ненавидеть себя за это сейчас.

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

Шкала HateYourselfLater™ находится в диапазоне от -10 до 10, где 10 означает наибольшее количество лайков, а -10 — наибольшее количество ненависти.

Оригинальный ответ:

Вам нужен декомпилятор. Есть несколько декомпиляторов Java, доступных на выбор, я перечислю несколько:

  • Showmycode — простой в использовании, приличная декомпиляция, онлайн (поэтому не подходит для корпоративных материалов), портит встроенные имена классов и вложенные анонимные классы
  • Jad — загружаемый, интерфейс командной строки, работает, но производит уродливый код, версия Linux устарела (при необходимости используйте версию Windows с вином), испорченные перечисления, циклы foreach и некоторые попытки/ловушки
  • Fernflower - CLI, трудно найти, лучший вывод из трех, автор ТАК пользователь, приличный вывод, иногда лажает попытка/ловит

Ни один из них не идеален, но это всего лишь результат того, что некоторые данные теряются при компиляции, и декомпиляторы должны угадать, как изначально выглядела программа.

person Wug    schedule 01.08.2012
comment
Я не понимаю, как «я хочу сгенерировать класс» можно решить с помощью декомпилятора. (что означает, что я или вы не поняли вопроса) - person Angelo Fuchs; 01.08.2012
comment
Нет. Я хочу создать класс java-util, который принимает три параметра (имена классов DTO, BO и имя класса Converter). Этот Util-класс создаст класс .java для сопоставления DTO с BO. - person VAm; 01.08.2012
comment
Итак... вы пытаетесь... программно написать класс Java? Здесь я подумал, что вы имели в виду, что он у вас есть и вам нужно получить исходный код для него. - person Wug; 01.08.2012
comment
@AngeloNeuschitzer: я мог бы просто отредактировать это. Оказывается, у меня тоже есть некоторый опыт отражения. - person Wug; 01.08.2012
comment
@VAm: можете ли вы опубликовать классы, между которыми вы хотите соединиться? или упрощенные версии, которые могут быть лучше. - person Wug; 01.08.2012
comment
@VAm: я был афк на минуту. У меня есть несколько вопросов и предложений, смотрите ответ. Во-первых, знаете ли вы имена полей, которые есть у каждого класса? Будут ли эти имена одинаковыми в обоих классах? Мало что можно сделать с точки зрения программного угадывания, каким переменным должны быть присвоены какие значения. - person Wug; 01.08.2012

Вы можете делать несколько вещей.

Вы ДОЛЖНЫ решить, что именно вы хотите сделать, а затем получить подходящую библиотеку, которая сделает это за вас, и изучите эту библиотеку.

BCEL — одна из таких библиотек. В прошлом я успешно использовал Java-APT для аналогичных целей.

Для вашего понимания я напишу кое-что о создании классов ниже, но, пожалуйста, не развивайте это самостоятельно, вы, скорее всего, застрянете.

Если вы хотите, чтобы ваш класс был доступен в той же JVM, которую вы сейчас используете (в отличие от: вы хотите сгенерировать код, а затем снова скомпилировать всю программу и перезапустить ее), вам необходимо:

  1. Создайте файл, напишите в него свою строку.
  2. Скомпилируйте файл (грубый способ сделать это вызовет javac из кода)
  3. загрузите классы в свой загрузчик классов.
person Angelo Fuchs    schedule 01.08.2012
comment
Вы читали вопрос? Потому что я перечитываю его (я тоже запутался :S), и это не похоже на ответ. - person Wug; 01.08.2012
comment
@Wug У него есть класс, который пишет файл .java (как я могу создать файл .java из строки) и хочет использовать этот файл в своей программе. Да, я прочитал вопрос. - person Angelo Fuchs; 01.08.2012
comment
Я думаю, что он хочет иметь класс, который работает таким образом, но пока этого не делает. - person Wug; 01.08.2012