Друзья, я недавно начал изучать Java. Сейчас пишу небольшую программу. Скажите пожалуйста, как реализовать в программе возврат (передача управления) к началу класса? Например, в конце программы спрашивается, хочет ли пользователь начать заново и при введение соответствующего символа, программа должна запуститься повторно то есть начать с класса Main. Как это можно реализовать?
Спасибо заранее всем за ответы.
- Вопрос задан более трёх лет назад
- 8492 просмотра
1 комментарий
Оценить 1 комментарий
Scanner RepetitionMethod = new Scanner(System.in);
System.out.print(«Would you like to explore the garage? (yes or no):»);
String quest = RepetitionMethod.nextLine();
if (quest.equals(«yes»)||quest.equals(«y»)||quest.equals(«1»)) System.out.println(«You see: Tv, Books, Car «);
break;
> else if (quest.equals(«no»)||quest.equals(«n»)||quest.equals(«0»)) System.out.println(«You not see «);
Java с нуля. Установка JDK на Windows
break;
>else System.out.println(«Error you need write (yes or no)»);
System.out.println(«Try again!»);
Решения вопроса 0
Ответы на вопрос 3
Как то так обычно это делается
package ru.toster.java.q241826; import java.util.Date; import java.util.Scanner; public class App < public static void main(String[] args) < Scanner scnr = new Scanner(System.in); while (true) < System.out.print(«enter command>»); String command = scnr.nextLine(); if («help».equals(command)) < printListCommand(); >else if («date».equals(command)) < printDate(); >else if («time».equals(command)) < printTime(); >else if («exit».equals(command)) < System.out.println(«Good Bye!»); break; >else < System.out.println(«Unknown command! Please enter ‘help'»); >> scnr.close(); > private static void printTime() < System.out.printf(«%1tTn», new Date()); >private static void printDate() < System.out.printf(«%1tY-%1$tm-%1$tdn», new Date()); >private static void printListCommand() < System.out.println( «‘help’tprint list commands;n» + «‘exit’texit from programm;n» + «‘date’tprint today’s date;n» + «‘time’tprint current time;»); >>
Ответ написан более трёх лет назад
Нравится 4 3 комментария
хорошо что вы обогащаете наши познания в java, но причем тут программа с приложенным списком для пользователя , чтобы он сделал выбор из предложных вами вариантов. Если вопрос заключается не в том как написать программу на java, чтобы из предложных программой ответов пользователь выбрал один и программа завершилось , а в том чтобы в конце программы выдавалось сообщение хочет ли пользователь начать заново и если да тогда запускалось программа по новой или я что то не понимаю здесь
Как полностью удалить Java в Windows 10
gausdrem: в моем примере есть все для этого, и возврат к началу, и выход
Eugene:извиняюсь, хорошо ну значит у меня еще не достаточный уровень знаний в этой области
Разработчик мобильных приложений для Android
Я бы сделала так:
class MyClass < public static void main (String [] args) < start(); >private void start() < // do something // ask user if he want to start again if (needStartAgain == true) < start(); >> >
Ответ написан более трёх лет назад
Нравится 1 7 комментариев

Марина Опять таки, вызывав большое количество функций start внутри самич себя вы получите переполнение стека вызова функций.

Эмин: Ну тут уж зависит от задачи. Если это просто лабораторная работа (а скорее всего это именно она), которая больше 8-10 раз запускаться не будет, то решение вполне сойдет. В реальных задачах такого, конечно, делать не стоит.

Марина: В лабе такого делать особенно не стоит, ибо это — указание на вопиющее непонимание предназначения рекурсии и принципов написания кода с детерминированным поведением. короче, садись, два 🙂
pi314: Смотря на что лаба. Может они до рекурсии еще и не дошли

Марина: да хоть на что лаба. писать плохой код НЕЛЬЗЯ! От каждой строчки такого кода умирает по одному котёнку 🙂
pi314: Спасибо, прочитаю о рекурсии

Python, Java+Android, Frontend
если у вас все в одном методе, то можно или в бесконечный цикл кинуть или рекурсивно метод вызывать
// Variant 1 class Lol < public void main(String[] args) < while(true) < // prog code // ввод от пользователя. Если символ не тот — break >> > // Variant 2 class Lol2 < public void main(String[] args) < // prog code // ввод от пользователя. Если символ тот — this.main(args) >>
Ответ написан более трёх лет назад

Oleg Wock Второй вариант вообще сомнительный. В первый раз вижу чтобы так делали(предлагали делать).

Oleg Wock К тому же если постоянно запускать одну main внутри другой, может переполниться стек.

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

Эмин: вполне. Поэтому я использую первый вариант
Компилятор ругается «There is no such reference available here»

Jonibek: какой способ?
Oleg Wock: Второй способ

Jonibek: используйте первый. Во втором я не был на 100% уверен (читайте выше). А если бы он и работал, то были бы проблемы
Oleg Wock: Сорри, но в первом варианте я не вижу выхода. Мне нужно реализовать алгоритм: ввод от пользователя — если символ тот — начать программу заново; если не тот — то закончить программу.

Jonibek: так в чем проблема. просто в конце условно такой код пишешь
if (!input().equals(«MySymbol»))
При вводе текста «MySymbol» оно пойдет по другому кругу, при сем-то ином перервет цикл и соответственно так как кода после цикла нет — завершит выполнение программы. Только функцию ввода заменить не забудь, я уже забыл как она называется (прогаю под Android)
я согласен примерно Oleg Wock я думаю на java конец программы должен быть таким System.out.println (» хочет ли пользователь начать заново «); // английскими буквами чтобы компилировал нормально
if (ввод от пользователя.equals(«тот символ»)) return class main;
else
System.out.println(«выход из программы»);

gausdrem: мало того, что вы возвращаете метод класса, вместо того что бы его вызывать, так еще return сам по себе перервет выполнение программы. А по поводу русских букв в терминале — он у вас не настроен (вы же на винде, да?)
ну и что что на винде по шилду break это прерывание он и прирвет программу а return это возврат смотри условие примера он сам просит что Например, в конце программы спрашивается, хочет ли пользователь начать заново и при введение соответствующего символа, программа должна запуститься повторно то есть начать с класса Main (я использую jdk 7 )

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

gausdrem: при брейке прерывается цикл, а не программа. В данном случае да, прервется и прога, но не из-за брейка, а из-за того, что после цикла нет кода, т.е. «программка кончилась»
по поводу оператора условия if тогда его можно писать либо с else либо без него, он будет выполняться так если условие истинно выполняется оператор 1 иначе оператор 2 , хорошо но если ты не заметил эта попытка была вызвать класс, а не метод если я хотел вызвать метод то для начала мне надо было его зарезервировать в памяти с помощью оператора new , а про возвращение значений 2 условия переменные должны быть одинакового типа и тип данных также. да он завершает программу и передает управление коду который его вызывал то есть по сути можно было просто написать return без указания class main это вы прочитайте еще раз условия вопроса. (Он пишет как реализовать в программе возврат к началу класса) но лично я не находил в книге пока еще чтобы в программе прямым кодом было прописано возврат к классу
Источник: qna.habr.com
Как перезапустить приложение Java?
Как перезапустить приложение Java AWT? У меня есть кнопка, к которой я привязал обработчик событий. Какой код следует использовать для перезапуска приложения?
Я хочу сделать то же самое, что Application.Restart() делать в приложении С#.
Лучший ответ:
Конечно, можно перезапустить Java-приложение.
Следующий способ показывает способ перезапуска приложения Java:
public void restartApplication() < final String javaBin = System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java»; final File currentJar = new File(MyClassInTheJar.class.getProtectionDomain().getCodeSource().getLocation().toURI()); /* is it a jar file? */ if(!currentJar.getName().endsWith(«.jar»)) return; /* Build command: java -jar application.jar */ final ArrayListcommand = new ArrayList(); command.add(javaBin); command.add(«-jar»); command.add(currentJar.getPath()); final ProcessBuilder builder = new ProcessBuilder(command); builder.start(); System.exit(0); >
В основном это делает следующее:
- Найти исполняемый файл java (здесь я использовал двоичный код java, но это зависит от ваших требований)
- Найти приложение (банку в моем случае, используя класс MyClassInTheJar , чтобы найти местоположение jar)
- Создайте команду для перезапуска jar (используя двоичный код java в этом случае)
- Выполните его! (и, таким образом, завершение текущего приложения и его запуск снова)
import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; public class Main < public static void main(String[] args) throws IOException, InterruptedException < StringBuilder cmd = new StringBuilder(); cmd.append(System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java «); for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) < cmd.append(jvmArg + » «); >cmd.append(«-cp «).append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(» «); cmd.append(Main.class.getName()).append(» «); for (String arg : args) < cmd.append(arg).append(» «); >Runtime.getRuntime().exec(cmd.toString()); System.exit(0); > >
Посвящается всем тем, кто говорит, что это невозможно.
Эта программа собирает всю информацию, доступную для восстановления исходной командной строки. Затем он запускает его, и поскольку он является той же самой командой, ваше приложение запускается во второй раз. Затем мы выходим из исходной программы, дочерняя программа продолжает работать (даже под Linux) и делает то же самое.
ПРЕДУПРЕЖДЕНИЕ. Если вы запустите это, имейте в виду, что он никогда не заканчивает создание новых процессов, подобно fork bomb.
В принципе, вы не можете. По крайней мере, не на надежном пути.
Чтобы перезапустить Java-программу, вам необходимо перезапустить JVM. Чтобы перезапустить JVM, вам необходимо
- Найдите используемую пусковую установку java . Вы можете попробовать с помощью System.getProperty(«java.home») , но нет гарантии, что это фактически укажет на панель запуска, которая была использована для запуска вашего приложения. (Возвращаемое значение может не указывать на JRE, используемое для запуска приложения, или оно могло быть переопределено -Djava.home .)
- Предположительно вы хотели бы почтить исходные настройки памяти и т.д. ( -Xmx , -Xms , ), поэтому вам нужно выяснить, какие настройки используются для запуска первой JVM. Вы можете попробовать использовать ManagementFactory.getRuntimeMXBean().getInputArguments() , но нет гарантии, что это отразит используемые настройки. Это даже указано в документации этого метода:
Как правило, не все параметры командной строки для команды “java” передаются на виртуальную машину Java. Таким образом, возвращаемые входные аргументы могут не включать все параметры командной строки.
С другой стороны: Вам не нужно.
Я рекомендую вам разработать ваше приложение, чтобы было легко чистить все, и после этого создать новый экземпляр вашего “основного” класса.
Многие приложения предназначены только для создания экземпляра в основном методе:
public class MainClass < . public static void main(String[] args) < new MainClass().launch(); >. >
Используя этот шаблон, должно быть достаточно легко сделать что-то вроде:
public class MainClass < . public static void main(String[] args) < boolean restart; do < restart = new MainClass().launch(); >while (restart); > . >
и пусть launch() возвращает true тогда и только тогда, когда приложение было отключено таким образом, что его необходимо перезапустить.
Строго говоря, Java-программа не может перезапускаться сама, так как для этого необходимо убить JVM, в которой она запущена, а затем запустить ее снова, но как только JVM больше не будет запущен (убит), никакие действия не могут быть предприняты.
Вы можете сделать некоторые трюки с пользовательскими загрузчиками классов для загрузки, упаковки и запуска компонентов AWT, но это, вероятно, вызовет много головных болей в отношении цикла событий GUI.
В зависимости от того, как приложение запускается, вы можете запустить JVM в оболочке script, которая содержит цикл do/while, который продолжается, пока JVM выходит с определенным кодом, тогда приложение AWT должно было бы вызвать System.exit(RESTART_CODE) . Например, в сценарии псевдокода:
DO # Launch the awt program EXIT_CODE = # Get the exit code of the last process WHILE (EXIT_CODE == RESTART_CODE)
Приложение AWT должно выйти из JVM с чем-то, отличным от RESTART_CODE, при “нормальном” завершении, которое не требует перезапуска.
Eclipse обычно перезапускается после установки плагина. Они делают это, используя оболочку eclipse.exe(приложение запуска) для окон. Это приложение запускает ядро ядра eclipse runner, и если приложение java eclipse завершается с помощью перезапуска кода, eclipse.exe перезапускает верстак. Вы можете создать аналогичный бит собственного кода, оболочки script или другой оболочки Java-кода для достижения перезапуска.
Если вам действительно нужно перезагрузить приложение, вы можете написать отдельное приложение, чтобы запустить его…
Эта страница содержит множество различных примеров для разных сценариев:
Несмотря на то, что этот вопрос старен и отвечает, я наткнулся на проблему с некоторыми решениями и решил добавить мое предложение в микс.
Проблема с некоторыми решениями заключается в том, что они строят одну командную строку. Это создает проблемы, когда некоторые параметры содержат пробелы, особенно java.home.
Например, в окнах строка
final String javaBin = System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java»;
Может получиться что-то вроде этого: C:Program FilesJavajre7binjava
Эта строка должна быть заключена в кавычки или экранирована из-за пробела в Program Files . Не большая проблема, но несколько раздражающая и подверженная ошибкам, особенно в кросс-платформенных приложениях.
Поэтому мое решение создает команду как массив команд:
public static void restart(String[] args) < ArrayListcommands = new ArrayList(4 + jvmArgs.size() + args.length); List jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); // Java commands.add(System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java»); // Jvm arguments for (String jvmArg : jvmArgs) < commands.add(jvmArg); >// Classpath commands.add(«-cp»); commands.add(ManagementFactory.getRuntimeMXBean().getClassPath()); // Class to be executed commands.add(BGAgent.class.getName()); // Command line arguments for (String arg : args) < commands.add(arg); >File workingDir = null; // Null working dir means that the child uses the same working directory String[] env = null; // Null env means that the child uses the same environment String[] commandArray = new String[commands.size()]; commandArray = commands.toArray(commandArray); try < Runtime.getRuntime().exec(commandArray, env, workingDir); System.exit(0); >catch (IOException e) < e.printStackTrace(); >>
Я сам изучал этот вопрос, когда наткнулся на этот вопрос.
Независимо от того, что ответ уже принят, я все же хотел бы предложить альтернативный подход для полноты. В частности, Apache Ant служил очень гибким решением.
В принципе, все сводится к файлу Ant script с одной задачей выполнения Java (см. здесь и здесь), вызывается из кода Java (см. here). Этот Java-код, который может быть запуском метода, может быть частью приложения, которое необходимо перезапустить. Приложение должно иметь зависимость от библиотеки Apache Ant (jar).
Когда приложение необходимо перезапустить, он должен вызывать метод запуска и выхода из виртуальной машины. Задача Ant java должна иметь параметры fork и spawn, установленные в true.
Вот пример Ant script:
Код метода запуска может выглядеть примерно так:
public final void launch(final String antScriptFile) < /* configure Ant and execute the task */ final File buildFile = new File(antScriptFile); final Project p = new Project(); p.setUserProperty(«ant.file», buildFile.getAbsolutePath()); final DefaultLogger consoleLogger = new DefaultLogger(); consoleLogger.setErrorPrintStream(System.err); consoleLogger.setOutputPrintStream(System.out); consoleLogger.setMessageOutputLevel(Project.MSG_INFO); p.addBuildListener(consoleLogger); try < p.fireBuildStarted(); p.init(); final ProjectHelper helper = ProjectHelper.getProjectHelper(); p.addReference(«ant.projectHelper», helper); helper.parse(p, buildFile); p.executeTarget(p.getDefaultTarget()); p.fireBuildFinished(null); >catch (final BuildException e) < p.fireBuildFinished(e); >/* exit the current VM */ System.exit(0);
Очень удобно, что тот же самый script используется для начального запуска приложения, а также для перезапуска.
Окно
public void restartApp() < // This launches a new instance of application dirctly, // remember to add some sleep to the start of the cmd file to make sure current instance is // completely terminated, otherwise 2 instances of the application can overlap causing strange // things:) new ProcessBuilder(«cmd»,»/c start /min c:/path/to/script/that/launches/my/application.cmd ^).start(); System.exit(0); >
/мин, чтобы запустить script в свернутом окне
^ new ProcessBuilder(getMyOwnCmdLine()).inheritIO().start(); >public static String[] getMyOwnCmdLine() throws IOException < return readFirstLine(«/proc/self/cmdline»).split(«u0000»); >public static String readFirstLine(final String filename) throws IOException < try (final BufferedReader in = new BufferedReader(new FileReader(filename))) < return in.readLine(); >>
В системах с доступным /proc/self/cmdline это, вероятно, самый элегантный способ “перезапуска” текущего Java-процесса с Java. Ни один JNI не участвовал, и не было никаких предположений о путях и необходимых вещах.
В настоящее время многие системы UNIX, включая GNU/Linux (включая Android), имеют procfs Однако на некоторых, подобных FreeBSD, это устарело и поэтапно вне. Mac OS X является исключением в том смысле, что у нее нет procfs. Windows также не имеет procfs. Cygwin имеет procfs, но он невидим для Java, потому что он виден только приложениям, использующим библиотеки Cygwin вместо системных вызовов Windows, а Java не знает о Cygwin.
Не забудьте использовать ProcessBuilder.inheritIO()
По умолчанию установлено, что stdin / stdout / stderr (в Java под названием System.in / System.out / System.err ) начального процесса установлены каналы, которые позволяют текущему запущенному процессу общаться с недавно начатым процессом. Если вы хотите перезапустить текущий процесс, это скорее всего не то, что вы хотите. Вместо этого вы хотели бы, чтобы stdin / stdout / stderr были такими же, как те, которые находятся в текущей виртуальной машине. Это называется унаследованным. Вы можете сделать это, вызвав inheritIO() вашего экземпляра ProcessBuilder .
Pitfall в Windows
Частым вариантом использования функции restart() является перезапуск приложения после обновления. Последний раз, когда я пробовал это в Windows, это было проблематично. При перезаписывании файла приложения .jar с новой версией приложение начало ошибочно вводить и предоставлять исключения в файле .jar . Я просто говорю, если это ваш прецедент. Тогда я решил проблему, обернув приложение в пакетный файл и используя магическое возвращаемое значение из System.exit() , которое я запросил в пакетном файле, и вместо этого пакетный файл перезапустил приложение.
Старый вопрос и все такое. Но это еще один способ, который дает некоторые преимущества.
В Windows вы можете попросить планировщик задач снова запустить приложение для вас. Преимущество этого заключается в том, что вы ожидаете определенное количество времени до перезапуска приложения. Вы можете перейти к диспетчеру задач и удалить задачу, и она перестает повторяться.
SimpleDateFormat hhmm = new SimpleDateFormat(«kk:mm»); Calendar aCal = Calendar.getInstance(); aCal.add(Calendar.SECOND, 65); String nextMinute = hhmm.format(aCal.getTime()); //Task Scheduler Doesn’t accept seconds and won’t do current minute. String[] create = ; Process proc = Runtime.getRuntime().exec(create, null, null); System.out.println(«Exit Now»); try catch (Exception e)<> // just so you can see it better System.exit(0);
Подобно ” улучшенному ” ответу Yoda, но с дальнейшими улучшениями (как функциональными, читабельными, так и тестируемыми). Теперь он безопасен для запуска и перезапускается столько же раз, сколько задано количество аргументов программы.
- Отсутствие JAVA_TOOL_OPTIONS .
- Автоматически находит основной класс.
- Наследует текущий stdout/stderr.
public static void main(String[] args) throws Exception < if (args.length == 0) return; else args = Arrays.copyOf(args, args.length — 1); Listcommand = new ArrayList<>(32); appendJavaExecutable(command); appendVMArgs(command); appendClassPath(command); appendEntryPoint(command); appendArgs(command, args); System.out.println(command); try < new ProcessBuilder(command).inheritIO().start(); >catch (IOException ex) < ex.printStackTrace(); >> private static void appendJavaExecutable(List cmd) < cmd.add(System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java»); >private static void appendVMArgs(Collection cmd) < CollectionvmArguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); String javaToolOptions = System.getenv(«JAVA_TOOL_OPTIONS»); if (javaToolOptions != null) < CollectionjavaToolOptionsList = Arrays.asList(javaToolOptions.split(» «)); vmArguments = new ArrayList<>(vmArguments); vmArguments.removeAll(javaToolOptionsList); > cmd.addAll(vmArguments); > private static void appendClassPath(List cmd) < cmd.add(«-cp»); cmd.add(ManagementFactory.getRuntimeMXBean().getClassPath()); >private static void appendEntryPoint(List cmd) < StackTraceElement[] stackTrace = new Throwable().getStackTrace(); StackTraceElement stackTraceElement = stackTrace[stackTrace.length — 1]; String fullyQualifiedClass = stackTraceElement.getClassName(); String entryMethod = stackTraceElement.getMethodName(); if (!entryMethod.equals(«main»)) throw new AssertionError(«Entry point is not a ‘main()’: » + fullyQualifiedClass + ‘.’ + entryMethod); cmd.add(fullyQualifiedClass); >private static void appendArgs(List cmd, String[] args)
V1.1 Bugfix: нулевой указатель, если JAVA_TOOL_OPTIONS не установлен
$ java -cp Temp.jar Temp a b c d e [/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a, b, c, d] [/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a, b, c] [/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a, b] [/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a] [/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp] $
System.err.println(«Someone is Restarting me. «); setVisible(false); try < Thread.sleep(600); >catch (InterruptedException e1) < e1.printStackTrace(); >setVisible(true);
Я думаю, вы действительно не хотите останавливать приложение, но “перезагрузите” его. Для этого вы можете использовать это и добавить свой “Reset” перед сном и после невидимого окна.
Источник: techarks.ru
Как я могу перезапустить приложение Java?
Как я могу перезапустить приложение Java AWT? У меня есть кнопка, к которой я прикрепил обработчик событий. Какой код я должен использовать, чтобы перезапустить приложение?
Я хочу сделать то же самое, что Application.Restart() сделать в приложении C#.
user233932 11 ноя ’10 в 22:15 2010-11-11 22:15
2010-11-11 22:15
13 ответов
Конечно, можно перезапустить приложение Java.
Следующий метод показывает способ перезапустить приложение Java:
public void restartApplication() < final String javaBin = System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java»; final File currentJar = new File(MyClassInTheJar.class.getProtectionDomain().getCodeSource().getLocation().toURI()); /* is it a jar file? */ if(!currentJar.getName().endsWith(«.jar»)) return; /* Build command: java -jar application.jar */ final ArrayListcommand = new ArrayList(); command.add(javaBin); command.add(«-jar»); command.add(currentJar.getPath()); final ProcessBuilder builder = new ProcessBuilder(command); builder.start(); System.exit(0); >
В основном это делает следующее:
- Найдите исполняемый файл Java (я использовал двоичный файл Java здесь, но это зависит от ваших требований)
- Найти приложение (баночка в моем случае, используя MyClassInTheJar класс, чтобы найти само место банку)
- Создайте команду для перезапуска jar (в этом случае используйте двоичный файл java)
- Выполните это! (и, таким образом, завершение текущего приложения и запуск его снова)
user246263 16 ноя ’10 в 12:42 2010-11-16 12:42
2010-11-16 12:42
import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; public class Main < public static void main(String[] args) throws IOException, InterruptedException < StringBuilder cmd = new StringBuilder(); cmd.append(System.getProperty(«java.home») + File.separator + «bin» + File.separator + «java «); for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) < cmd.append(jvmArg + » «); >cmd.append(«-cp «).append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(» «); cmd.append(Main.class.getName()).append(» «); for (String arg : args) < cmd.append(arg).append(» «); >Runtime.getRuntime().exec(cmd.toString()); System.exit(0); > >
Посвящается всем тем, кто говорит, что это невозможно.
Эта программа собирает всю информацию, доступную для восстановления оригинальной командной строки. Затем он запускает его, и поскольку это та же команда, ваше приложение запускается во второй раз. Затем мы выходим из исходной программы, дочерняя программа остается запущенной (даже под Linux) и делает то же самое.
ВНИМАНИЕ: Если вы запустите это, имейте в виду, что это никогда не заканчивается созданием новых процессов, подобных бомбе-вилке.
user102498 12 ноя ’10 в 00:19 2010-11-12 00:19
2010-11-12 00:19
По сути, вы не можете. По крайней мере, не надежным способом.
Чтобы перезапустить программу Java, вам нужно перезапустить JVM. Чтобы перезапустить JVM, вам нужно
- Найдите java пусковая установка, которая была использована. Вы можете попробовать с System.getProperty(«java.home») но нет гарантии, что это на самом деле будет указывать на панель запуска, которая использовалась для запуска вашего приложения. (Возвращаемое значение может не указывать на JRE, использованную для запуска приложения, или оно могло быть переопределено -Djava.home .)
- Вы, вероятно, хотели бы соблюдать оригинальные настройки памяти и т. Д. ( -Xmx , -Xms … Так что вам нужно выяснить, какие настройки использовались для запуска первой JVM. Вы можете попробовать использовать ManagementFactory.getRuntimeMXBean().getInputArguments() но нет гарантии, что это будет отражать используемые настройки. Это даже прописано в документации этого метода:
Как правило, не все параметры командной строки команды java передаются на виртуальную машину Java. Таким образом, возвращаемые входные аргументы могут не включать все параметры командной строки.
С другой стороны: вам не нужно.
Я рекомендую вам спроектировать ваше приложение так, чтобы было легко очистить каждую вещь, а после этого создать новый экземпляр вашего «основного» класса.
Многие приложения предназначены только для создания экземпляра в методе main:
public class MainClass < . public static void main(String[] args) < new MainClass().launch(); >. >
Используя этот шаблон, должно быть достаточно легко сделать что-то вроде:
public class MainClass < . public static void main(String[] args) < boolean restart; do < restart = new MainClass().launch(); >while (restart); > . >
и разреши launch() верните true тогда и только тогда, когда приложение было закрыто так, что его необходимо перезапустить.
user276052 11 ноя ’10 в 22:20 2010-11-11 22:20
2010-11-11 22:20
Строго говоря, Java-программа не может перезапустить себя, поскольку для этого она должна завершить работу JVM, в которой она выполняется, а затем запустить ее снова, но как только JVM больше не работает (не завершается), никакие действия не могут быть предприняты.
Вы могли бы сделать некоторые трюки с пользовательскими загрузчиками классов, чтобы загрузить, упаковать и запустить компоненты AWT снова, но это, вероятно, вызовет много головной боли в отношении цикла событий GUI.
В зависимости от того, как запущено приложение, вы можете запустить JVM в сценарии-оболочке, который содержит цикл do/while, который продолжается, пока JVM завершает работу с определенным кодом, тогда приложение AWT должно будет вызвать System.exit(RESTART_CODE) , Например, в сценарии псевдокод:
DO # Launch the awt program EXIT_CODE = # Get the exit code of the last process WHILE (EXIT_CODE == RESTART_CODE)
Приложение AWT должно выйти из JVM с чем-то отличным от RESTART_CODE при «нормальном» завершении, которое не требует перезапуска.
user244128 11 ноя ’10 в 22:23 2010-11-11 22:23
2010-11-11 22:23
Windows
public void restartApp() < // This launches a new instance of application dirctly, // remember to add some sleep to the start of the cmd file to make sure current instance is // completely terminated, otherwise 2 instances of the application can overlap causing strange // things:) new ProcessBuilder(«cmd»,»/c start /min c:/path/to/script/that/launches/my/application.cmd ^).start(); System.exit(0); >
/ мин, чтобы запустить скрипт в свернутом окне
^ new ProcessBuilder(getMyOwnCmdLine()).inheritIO().start(); >public static String[] getMyOwnCmdLine() throws IOException < return readFirstLine(«/proc/self/cmdline»).split(«u0000»); >public static String readFirstLine(final String filename) throws IOException < try (final BufferedReader in = new BufferedReader(new FileReader(filename))) < return in.readLine(); >>
На системах с /proc/self/cmdline доступно, это, вероятно, самый элегантный способ «перезапустить» текущий процесс Java из Java. Никакой JNI не задействован, и не нужно угадывать пути и прочее.
Многие UNIX-системы, включая GNU/Linux (включая Android), в настоящее время имеют procfs. Однако в некоторых, таких как FreeBSD, это устарело и постепенно прекращается. Mac OS X является исключением в том смысле, что у него нет procfs. Windows также не имеет procfs. У Cygwin есть procfs, но он невидим для Java, потому что он виден только приложениям, использующим библиотеки Cygwin вместо системных вызовов Windows, а Java не знает о Cygwin.
Не забудьте использовать ProcessBuilder.inheritIO()
По умолчанию это stdin / stdout / stderr (в Java называется System.in / System.out / System.err ) запущенного Процесса устанавливаются в каналы, которые позволяют текущему запущенному процессу взаимодействовать с вновь запущенным процессом. Если вы хотите перезапустить текущий процесс, скорее всего, это не то, что вам нужно. Вместо этого вы хотели бы этого stdin / stdout / stderr такие же, как у текущей виртуальной машины. Это называется наследственным. Вы можете сделать это, позвонив inheritIO() вашей ProcessBuilder пример.
Ловушка на Windows
Частый случай использования restart() Функция состоит в том, чтобы перезапустить приложение после обновления. В прошлый раз, когда я попробовал это на Windows, это было проблематично. Когда переписали приложения .jar файл с новой версией, приложение начало плохо себя вести и дает исключения о .jar файл. Я просто говорю, на случай, если это ваш вариант использования. Тогда я решил проблему, поместив приложение в командный файл и использовав магическое возвращаемое значение из System.exit() что я запросил в командном файле, и вместо этого командный файл перезапустил приложение.
Источник: stackru.com