Задать вопрос
  • Как запустить 10000 классов в java?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Java
    Седой и строгий
    Прежде всего нужно заметить, что запустить класс нельзя, его можно только объявить, а запускать можно методы экземпляров этого класса. Почему я и подумал, что вопрос неправильно сформулирован.

    Но если уж вопрос именно об объявлении новых классов в рантайме, то это называется кодогенерацией. И, во-первых, рефлексия в этом бессильна, а во-вторых, это очень сложная тема, озадачить которой начинающего программиста мог только очень мерзкий тролль.

    Генерировать можно как java-код, так и байткод. Первый способ использует популярная библиотека Lombok. Для него понадобиться механизм работы с AST и механизм взаимодействия с компилятором. Oracle JDK и Open JDK предоставляют Compiler API, реализующий оба механизма. Кроме того, есть и другие инструменты для работы с AST, например Eclipse JDT. Я покажу применение пакета com.sun.tools.javac из Compiler API.
    Сноска
    До Java 9 пакет com.sun.tools.javac был упакован в tools.jar, поставляемый вместе с JDK. Начиная с 9-ки API компилятора вынесли в модуль jdk.compiler, не экспортирующие свои пакеты. Теперь можно не указывать путь до tools.jar в classpath, но нужно добавлять экспорты. В остальном ничего не изменилось.
    import java.lang.reflect.Method;
    import java.net.URI;
    import java.util.ArrayList;
     
    import javax.tools.JavaCompiler;
    import javax.tools.JavaCompiler.CompilationTask;
    import javax.tools.JavaFileObject;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.ToolProvider;
    
    import com.sun.tools.javac.code.Flags;
    import com.sun.tools.javac.code.Type;
    import com.sun.tools.javac.file.JavacFileManager;
    import com.sun.tools.javac.model.JavacElements;
    import com.sun.tools.javac.processing.JavacProcessingEnvironment;
    import com.sun.tools.javac.tree.JCTree;
    import com.sun.tools.javac.tree.TreeMaker;
    import com.sun.tools.javac.util.Context;
    import com.sun.tools.javac.util.List;
    import com.sun.tools.javac.util.Name;
    
    
    /**
     * Класс эмулирующий для компилятора файлы исходного кода
     * и позволяющий компилировать код прямо из памяти
     */
    class JavaSourceFromString extends SimpleJavaFileObject {
        private final String code;
    
        public JavaSourceFromString(String name, String code) {
            super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.code = code;
        }
    
        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return code;
        }
    }
     
    public class CompilerDemo {
        private static final String BASE_NAME = "DynamicHello";
        private static final ClassLoader classLoader = ToolProvider.getSystemToolClassLoader();
        private static final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    
        /**
         * Метод формирующий абстрактное синтаксическое дерево
         * и преобразующий его в исходный код
         */
        private static String generateSource(String className) {
            Context ctx = new Context();
            JavacFileManager.preRegister(ctx);
            TreeMaker treeMaker = TreeMaker.instance(ctx);
            JavacElements elements = JavacElements.instance(ctx);
    
            JCTree.JCModifiers modifiers = treeMaker.Modifiers(Flags.PUBLIC);
    
            // Тело генерируемого метода
            // выводящее имя класса
            JCTree.JCBlock methodBody = treeMaker.Block(0, List.of(
                treeMaker.Exec(
                    treeMaker.Apply(
                        List.<JCTree.JCExpression>nil(),
                        treeMaker.Select(
                            treeMaker.Select(
                                treeMaker.Ident(
                                    elements.getName("System")
                                ),
                                elements.getName("out")
                            ),
                            elements.getName("println")
                        ),
                        List.<JCTree.JCExpression>of(
                            treeMaker.Binary(
                                JCTree.Tag.PLUS,
                                treeMaker.Literal("I am "),
                                treeMaker.Apply(
                                    List.<JCTree.JCExpression>nil(),
                                    treeMaker.Select(
                                        treeMaker.Apply(
                                            List.<JCTree.JCExpression>nil(),
                                            treeMaker.Select(
                                                treeMaker.Ident(
                                                    elements.getName("this")
                                                ),
                                                elements.getName("getClass")
                                            ),
                                            List.<JCTree.JCExpression>nil()
                                        ),
                                        elements.getName("getName")
                                    ),
                                    List.<JCTree.JCExpression>nil()
                                )
                            )
                        )
                    )
                )
            ));
    
            // Определение генерируемого метода
            JCTree.JCMethodDecl method = treeMaker.MethodDef(
                modifiers,
                elements.getName("introduceYourself"),
                treeMaker.Type(new Type.JCVoidType()),
                List.<JCTree.JCTypeParameter>nil(),
                List.<JCTree.JCVariableDecl>nil(),
                List.<JCTree.JCExpression>nil(),
                methodBody,
                null
            );
    
            // Определение генерируемого класса
            JCTree.JCClassDecl tree = treeMaker.ClassDef(
                modifiers,
                elements.getName(className),
                List.<JCTree.JCTypeParameter>nil(),
                null,
                List.<JCTree.JCExpression>nil(),
                List.of(method)
            );
    
            return tree.toString();
        }
    
        /**
         * Метод компилирующий исходный код
         */
        public static void compile(Iterable<? extends JavaFileObject> compilationUnits) {
            CompilationTask task = compiler.getTask(null, null, null, null, null, compilationUnits);
            task.call();    
        }
    
    
        /**
         * Метод запускающий сгенерированные классы с помощью рефлексии
         */    
        public static void loadAndRun(String className) throws ReflectiveOperationException {
            Class<?> cls = classLoader.loadClass(className);
            
            Method method = cls.getDeclaredMethod("introduceYourself");
            method.invoke(cls.newInstance());    
        }
    
        public static void main(String[] args) throws Exception {
            java.util.List<JavaFileObject> sources = new ArrayList<>();
    
            // Генерируем исходный код десятка классов
            for (int x = 0; x < 10; x++) {
                String className = BASE_NAME + x;
                sources.add(new JavaSourceFromString(className, generateSource(className)));
            }
    
            // Компилируем сгенерированный код
            compile(sources);
            
            // Запускаем скомпилированные классы
            for (int x = 0; x < 10; x++) {
                loadAndRun(BASE_NAME + x);
            }
        }
    }

    Конечно, можно было не заморачиваться с AST, просто засунуть код в строковый литерал, подставлять в этот литерал разные имена и подсовывать компилятору. Но это не так интересно!

    Продолжение в первом комментарии, а то я в лимит символов не укладываюсь.
    Ответ написан
    3 комментария
  • Java на уровне железа, отличия от C++?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Авторы надеялись, что к железу можно будет обращаться с помощью абстракций - производитель железа у себя реализует java-машину, а уж сверху нее можно запускать прикладной код.

    Вы забываете о большом пласте истории техники, который был сильно до этого - 8 битные домашние ЭВМ (десятки их) и язык Бейсик.

    Так вот, ЭВМ того времени были катастрофически разными - разные носители (кассеты, дискеты, картриджи), разная аппаратура (засунуть еще один центральный процессор в дисковод? да нивапрос! разная скорость для PAL и NTSC версий - легко!). Но вот бейсик был везде и позволял, с некоторыми переделками, таскать программы с машины на машину.

    Таким образом, авторы находились в этом историческом контексте (у них все детство прошло в обнимку с каким-нибудь VIC-20). Тут уже становится логичным желание сотворить то же самое, только круче - берем современный язык, стандартизируем синтаксис - и делаем аналогично - производитель железа предоставляет нам Java-машину с нужным уровнем абстракции - и все программы бегают с архитектуры на архитектуру без переделок.

    Отчасти, это сработало на старых мобилках, в эпоху j2me - это как раз Java, засунутая в телефон - игры, браузеры, карты (были даже ЯндексКарты), читалки, чатилки - куча всего.

    Еще один виток эволюции, которые вы, видимо, не застали - (чорд, я - стар, я очень стар) - попытки сотворить интерактивные веб страницы.
    "У нас же есть всюду переносимая Java - давайте влупим ее поддержку в браузер в виде апплетов - небольших приложений". Тут резко активировались вирусописатели и прочий сброд - благодаря развесистой и дырявой архитектуре, апплеты могли творить всякую дичь.

    Сейчас апплет на java можно встретить во всяком старом железе, на нем там сделано GUI для удаленного администрирования серверов, коммутаторов и СХД. Вы браузером заходите на железку, и тут на вас вываливается ворох предупреждений о том, что сейчас будет запущено какое-то ужасное дырявое ПО, держите штаны, а то слетят. Уверены? Точно уверены? А с этим согласны? А так?

    А уже потом начали активно применять JavaScript, главным образом, изобретя Ajax - продолжая люто натягивать сову (систему для создания электронных библиотек для ученых/HTML) на глобус (задачу создания интерактивного гуя с красивой версткой).

    И это вы еще бэк на Perle не рефакторили
    Ответ написан
    2 комментария
  • Почему не получается вывести шорткод в шаблоне Wordpress?

    Mike_Ro
    @Mike_Ro Куратор тега WordPress
    Python, JS, WordPress, SEO, Bots, Adversting
    Вариант с экранированием:
    <?php echo do_shortcode( '[gridmaster grid_style="style-2" post_type="game" posts_per_page="10" orderby="date" order="DESC" content_from="excerpt" excerpt_type="characters" excerpt_length="15" show_read_more="yes" read_more_text="Скачать" grid_image_size="medium" grid_image_width="350" grid_image_height="200" link_thumbnail="no" link_thumbnail_to="post" show_filter="yes" filter_style="default" btn_all="no" taxonomy="category" hide_empty="1" multiple_select="no" toggle_filter_items="no" pagination_type="load_more" infinite_scroll="true" animation="true" heading_font_size=\'{"xs":"16px","sm":"18px","md":"20px","lg":"22px","xl":"24px"}\' grid_col_gap=\'{"xs":"30","sm":"30","md":"30","lg":"30","xl":"30"}\' grid_row_gap=\'{"xs":"30","sm":"30","md":"30","lg":"30","xl":"30"}\' grid_item_per_row=\'{"xs":"1","sm":"2","md":"3","lg":"3","xl":"3"}\' slider_args=\'{"arrows":"1","autoplaySpeed":"3000","infinite":"1","slidesToShow":{"xs":"1","sm":"2","md":"3","lg":"3","xl":"3"},"slidesToScroll":{"xs":"1","sm":"1","md":"1","lg":"1","xl":"1"}}\']' ); ?>

    Вариант с NOWDOC синтаксисом, как подсказал Ivan Ustûžanin:
    <?php echo do_shortcode( '[gridmaster grid_style="style-2" post_type="game" posts_per_page="10" orderby="date" order="DESC" content_from="excerpt" excerpt_type="characters" excerpt_length="15" show_read_more="yes" read_more_text="Скачать" grid_image_size="medium" grid_image_width="350" grid_image_height="200" link_thumbnail="no" link_thumbnail_to="post" show_filter="yes" filter_style="default" btn_all="no" taxonomy="category" hide_empty="1" multiple_select="no" toggle_filter_items="no" pagination_type="load_more" infinite_scroll="true" animation="true" heading_font_size=\'{"xs":"16px","sm":"18px","md":"20px","lg":"22px","xl":"24px"}\' grid_col_gap=\'{"xs":"30","sm":"30","md":"30","lg":"30","xl":"30"}\' grid_row_gap=\'{"xs":"30","sm":"30","md":"30","lg":"30","xl":"30"}\' grid_item_per_row=\'{"xs":"1","sm":"2","md":"3","lg":"3","xl":"3"}\' slider_args=\'{"arrows":"1","autoplaySpeed":"3000","infinite":"1","slidesToShow":{"xs":"1","sm":"2","md":"3","lg":"3","xl":"3"},"slidesToScroll":{"xs":"1","sm":"1","md":"1","lg":"1","xl":"1"}}\']' ); ?>

    Если использовать нормальную IDE, то она сообщит о возможных проблемах:
    67347946022ff024286243.png
    Ответ написан
    1 комментарий
  • Как эффективно перейти на c++ при опыте работе с php?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Посоветуйте, как можно было бы максимально безболезненно восполнить утраченные знания, а также наверстать упущенные новшества в языке?

    так это...
    Сейчас хочу попробовать реализовать научный проект.
    Собсно практика - лучший учитель, садитесь и пишите. Если базу уже знаете реализация не станет проблемой. По ходу решения текущих задач проекта познакомитесь со всеми нужными изменениями и практиками, сегодня на любой чих есть дока, туториал, видео и чатжпт. Двух зайцев двумя плюсами, так сказать...
    Ответ написан
    Комментировать
  • Почему 404 not found в ubuntu?

    @Drno
    А Вы права вебсерверу дали на папку и файлы ?
    это который пользователь www-data
    Ответ написан
    1 комментарий
  • Существует ли сервис бесплатных push Для android?

    Вроде в firebase нет ограничений на пуши (бесплатно и сколько угодно)
    По-умолчанию есть квота в 600к в минуту, но если очень-очень нужно, то можно попросить больше.
    https://firebase.google.com/docs/cloud-messaging/c...

    Очень много пушей за очень малое время не получится отправить (нужно размазывать на несколько минут) и на такое получить квоту нельзя принципиально.
    https://firebase.google.com/support/faq#fcm-quotas

    Также рейт лимиты могут быть ограничены в пики, когда большая нагрузка на сервис, по тому нужно обрабатывать нормально ошибку 429 и равномерно размазывать свои уведомления в течение дня.
    https://firebase.google.com/docs/cloud-messaging/c...

    600к отправок в месяц, если они размазаны - это мало и врядли упрётся в какой-либо лимит.
    Ответ написан
    3 комментария
  • Не работает Tails на ноутбуке honor magicbook 14 art, прошу помощи уважаемые знатоки. Сдавать в магазин или можно решить данную проблему?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Да, вернуть обратно в магазин и перед покупкой следующего ноутбука проверить его совместимость с линуксом.
    Ответ написан
    6 комментариев
  • В чем смысл папки assets в WP?

    vpetrov
    @vpetrov
    частный SEO-специалист
    Это часть традиционной архитектуры системы. Файлы шаблона стоит хранить вместе, чтобы потом, когда вы станете настраивать сканирование и индексацию сайта, вам не пришлось мучиться с настройками доступов. Да и поддерживать проект будет сильно проще.
    Ответ написан
    2 комментария
  • В чем смысл папки assets в WP?

    gagarinstudio
    @gagarinstudio
    Скорее больше для группировки файлов CSS, JS, images, fonts.
    Никакой критичной функциональности данная папка - не несет.

    Если заглянуть в репозиторий WP themes, то там видно, что файлы в старых версиях разбросаны по корневой директории темы, а потом группируются в assets
    Ответ написан
    Комментировать
  • Как заменить $('#more').ready(function() { на чистом js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    document.addEventListener('DOMContentLoaded', () => {
        // ...
    }, {once: true});
    Ответ написан
    2 комментария
  • Как настроить размещение адресной строки android firefox внизу?

    Elaryks
    @Elaryks
    Меню (три точки) → Настройки → Персонализация → Расположение адресной строки → Снизу.
    Ответ написан
    3 комментария
  • Как можно упростить код?

    rusyska55011
    @rusyska55011
    Сложи переменные и значения 'width' в массив и проходись по нему циклом, вставляя эти значения в вызываемый метод
    Ответ написан
    Комментировать
  • Как отсортировать массив по значению?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Ответ написан
    Комментировать
  • Как закрыть страницу благодарности от прямых заходов?

    kawabanga
    @kawabanga
    1) Получать с сервера ссылку, а не подставляя ее в js.
    2) Записывать куда то определенный hash на открытие страницы
    https://мойсайт.ru/страница-благодарности.php?hash=123 и потом гасить его, чтобы человек не мог повторно открыть страницу.

    Возможно просто рендер страницы благодарности вместо формы отрисовать после события успешной отправки формы.
    Ответ написан
    2 комментария
  • Как запретить перетаскивание img с зажатой левой кнопкой мыши?

    Добавьте pointer-events: none; в класс картинки.
    Ответ написан
    Комментировать
  • Можно ли разветвить патч корд на 2 wifi роутера?

    Провайдер тебе даёт всего 1 IP адрес, по тому именно разветвить тебе не получится, как ни старайся (как правило)

    Вставляй кабель от провайдера в wan-порт первого роутера.
    От первого роутера потом тащи кабель до второго.
    Второй роутер переведи в режим точки доступа.

    Таким образом за маршрутизацию и поддержание локальной сети будет отвечать первый роутер.
    Второй будет выполнять лишь роль коммутатора и точки доступа к этой сети.

    (сделано допущение, что "роутером" названо домашнее устройство с функциями маршрутизатора и wifi-точки доступа)
    Ответ написан
    Комментировать
  • Как исправить Warning: preg_replace(): Delimiter must not be alphanumeric or backslash?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Регулярное выражение должно быть обёрнуто символом-разделителем. У вас первый символ - слэш, он и считается разделителем, но быть разделителем не может.
    -"\[cp_theme:([_a-zA-Z0-9\]*)\]"
    +"~\[cp_theme:([_a-zA-Z0-9]*)\]~"


    Быстрее было бы найти ответ в поисковике, чем оформлять вопрос здесь.
    Ответ написан
    5 комментариев
  • Как значения из одного массива преобразовать в другой массив?

    vhood
    @vhood
    Не забывайте отмечать решения
    С помощью функций для работы с массивами и/или конструкций для итерации массивов.

    UPD:
    Если только configuration_value, то можно напрямую
    //$array - исходный массив
    //$configurationValue - новый массив
    $configurationValue = $array['configuration_value'];
    Однако смысла в этом никогда нет, только память расходовать. Значения по ключу можно получать там, где это нужно, не сохраняя их в отдельную переменную.
    Ответ написан
    Комментировать
  • Почему ломаются стили (CSS) в WindowsServer2012R2 (IIS8.5)?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Вероятно стили подключаются относительным путём

    <link href="style.css">

    А следует использовать абсолютный

    <link href="/style.css">
    Ответ написан
    8 комментариев
  • Существует ли хостинг с MacOS?

    Wispik
    @Wispik
    Полчаса поиска в гугле выдали только зарубежные хостинги с ценами по 100+ баксов за М1 версию

    Не знаю, как так можно гуглить. Вот, что я нашёл, за 2 минуты:
    https://mrhost.biz/store/vps-germany от 8 гб оперативы надо выбрать сервер
    https://ultahost.com/ru/mac-vps-hosting

    Ещё селектел, но там цены от 11к
    Ответ написан
    1 комментарий