Рубрики
Без рубрики

Краткое руководство по java.lang.Система

Изучите все классные советы и рекомендации, о которых вы никогда не слышали, с помощью java.lang.Система, например, как перенаправить System.out и безопасное использование System.nanoTime

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы быстро рассмотрим файл java.lang.System класс и его особенности и основные функциональные возможности.

2. ИО

System является частью java.lang , и одна из его основных функций-предоставить нам доступ к стандартным потокам ввода-вывода.

Проще говоря, он выставляет три поля, по одному для каждого потока:

  • из
  • ошибаться
  • в

2.1. System.out

System.out указывает на стандартный выходной поток, выставляя его как PrintStream , и мы можем использовать его для печати текста на консоль:

System.out.print("some inline message");

Расширенное использование System заключается в вызове System.setOut , который мы можем использовать для настройки местоположения, в которое System.out будет писать:

// Redirect to a text file
System.setOut(new PrintStream("filename.txt"));

2.2. System.err

System.err очень похоже на System.out . Оба поля являются экземплярами PrintStream, и оба предназначены для печати сообщений на консоль.

Но System.err представляет собой стандартную ошибку, и мы используем ее специально для вывода сообщений об ошибках:

System.err.print("some inline error message");

Консоли часто отображают поток ошибок иначе, чем выходной поток.

Для получения дополнительной информации обратитесь к документации PrintStream .

2.3. System.in

System.in указывает на стандарт in, выставляя его как InputStream, и мы можем использовать его для чтения входных данных с консоли.

И хотя мы немного больше вовлечены, мы все еще можем справиться:

public String readUsername(int length) throws IOException {
    byte[] name = new byte[length];
    System.in.read(name, 0, length); // by default, from the console
    return new String(name);
}

Вызывая System.in.read , приложение останавливается и ждет ввода от стандартного in. Какой бы ни была следующая длина байта, она будет считана из потока и сохранена в массиве байтов.

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

Конечно, работа на таком низком уровне может быть сложной и подверженной ошибкам, поэтому мы можем немного очистить ее с помощью BufferedReader :

public String readUsername() throws IOException {
    BufferedReader reader = new BufferedReader(
      new InputStreamReader(System.in));
    return reader.readLine();
}

При приведенном выше расположении readLine будет читать из System.in пока пользователь не нажмет return, что немного ближе к тому, что мы могли бы ожидать.

Обратите внимание, что мы намеренно не закрываем поток в этом случае. Закрытие стандарта in означает, что он не может быть прочитан снова в течение всего жизненного цикла программы!

И, наконец, расширенное использование System.in is to call System.setting to redirect it to a different InputStream .

3. Полезные Методы

Система предоставляет нам множество методов, чтобы помочь нам с такими вещами, как:

  • Доступ к консоли
  • Копирование массивов
  • Дата и время наблюдения
  • Выход из JRE
  • Доступ к свойствам среды выполнения
  • Доступ к переменным среды и
  • Администрирование сборки мусора

3.1. Доступ к консоли

Java 1.6 ввела другой способ взаимодействия с консолью, чем просто прямое использование System.out и in .

Мы можем получить доступ к нему, вызвав System.console :

public String readUsername() {
    Console console = System.console();	 	 
	 	 
    return console == null ? null :	 
      console.readLine("%s", "Enter your name: ");	 	 
}

Обратите внимание, что в зависимости от базовой операционной системы и того, как мы запускаем Java для запуска текущей программы, console может возвращать null, поэтому всегда обязательно проверяйте перед использованием .

Для получения дополнительной информации ознакомьтесь с документацией Console .

3.2. Копирование Массивов

System.arraycopy -это старый способ копирования одного массива в другой в стиле Си.

В основном, arraycopy предназначен для копирования одного полного массива в другой массив:

int[] a = {34, 22, 44, 2, 55, 3};
int[] b = new int[a.length];

System.arraycopy(a, 0, b, 0, a.length);
assertArrayEquals(a, b);

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

Например, предположим , что мы хотим скопировать 2 элемента из a , начиная с a[1] в b , начиная с b[3] :

System.arraycopy(a, 1, b, 3, 2); 
assertArrayEquals(new int[] {0, 0, 0, 22, 44, 0}, b);

Кроме того, помните, что arraycopy будет бросать:

  • NullPointerException если любой массив равен null
  • IndexOutOfBoundsException если копия ссылается на любой массив за пределами его диапазона
  • ArrayStoreException если копия приводит к несоответствию типов

3.3. Дата и время наблюдения

Есть два метода, связанных со временем в System . Один из них – currentTimeMillis , а другой – nanoTime .

currentTimeMillis возвращает количество миллисекунд, прошедших с начала эпохи Unix, то есть 1 января 1970 года в 12:00 по UTC:

public long nowPlusOneHour() {
    return System.currentTimeMillis() + 3600 * 1000L;
}

public String nowPrettyPrinted() {
    return new Date(System.currentTimeMillis()).toString();
}

nanoTime возвращает время относительно запуска JVM. Мы можем вызвать его несколько раз, чтобы отметить прохождение времени в приложении:

long startTime = System.nanoTime();
// ...
long endTime = System.nanoTime();

assertTrue(endTime - startTime < 10000);

Обратите внимание, что поскольку nanoTime настолько мелкозернист, безопаснее делать EndTime – startTime < 10000 , чем EndTime < startTime из-за возможности числового переполнения .

3.4. Выход из Программы

Если мы хотим программно выйти из текущей выполняемой программы, то System.exit сделает свое дело.

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

По соглашению в Unix состояние 0 означает нормальный выход, в то время как ненулевое означает, что произошла какая-то ошибка:

if (error) {
    System.exit(1);
} else {
    System.exit(0);
}

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

3.5. Доступ К свойствам среды выполнения

System предоставляет доступ к свойствам среды выполнения с помощью getProperty .

И мы можем управлять ими с помощью setProperty и clear Property :

public String getJavaVMVendor() {
    System.getProperty("java.vm.vendor");
}
    
System.setProperty("abckey", "abcvaluefoo");
assertEquals("abcvaluefoo", System.getProperty("abckey"));

System.clearProperty("abckey");
assertNull(System.getProperty("abckey"));

Свойства, указанные через -D , доступны через getProperty .

Мы также можем предоставить дефолт:

System.clearProperty("dbHost");
String myKey = System.getProperty("dbHost", "db.host.com");
assertEquals("db.host.com", myKey);

И System.GetProperties предоставляет коллекцию всех системных свойств:

Properties properties = System.getProperties();

Из которого мы можем делать любые Свойства операции:

public void clearAllProperties() {
    System.getProperties().clear();
}

3.6. Доступ к Переменным среды

System также предоставляет доступ только для чтения к переменным среды с помощью getenv .

Например, если мы хотим получить доступ к переменной окружения PATH , мы можем сделать:

public String getPath() {
    return System.getenv("PATH");
}

3.7. Администрирование Сбора Мусора

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

System.runFinalization – это метод, который позволяет нам предложить JVM запустить свою процедуру finalize.

System.gc – это метод, который позволяет нам предложить JVM запустить свою процедуру сборки мусора.

Поскольку контракты этих двух методов не гарантируют выполнения финализации или сборки мусора, их полезность узка.

Однако они могут быть использованы в качестве оптимизации, например, вызов gc когда настольное приложение сворачивается:

public void windowStateChanged(WindowEvent event) {
    if ( event == WindowEvent.WINDOW_DEACTIVATED ) {
        System.gc(); // if it ends up running, great!
    }
}

Подробнее о доработке читайте в нашем руководстве по доработке .

4. Заключение

В этой статье мы познакомимся с некоторыми полями и методами, которые предоставляет |/System . Полный список можно найти в официальной документации системы .

Кроме того, проверьте все примеры в этой статье на Github .