Перейти к содержимому

Package com company что это java

  • автор:

Почему некоторые пакеты в java начинаются с com. ? что такое com?

Это просто определение пространства имен, чтобы избежать столкновения имен классов. com.domain.package.Class -это установленное соглашение Java, в котором пространство имен квалифицируется с доменом компании в обратном порядке (то есть, имя пространства имён com.oracle.jdbc в перевернутом виде превратится в более привычное jdbc.oracle.com — что уже очень похоже на «имя сайта, куда надо ходить за jdbc драйвером для оракла»).

Отслеживать

11k 1 1 золотой знак 23 23 серебряных знака 44 44 бронзовых знака

Пакеты классов, package

Пакет package позволяет логически объединить классы в наборы. Основные классы java входят в пакет java.lang. Различные вспомогательные классы располагаются в пакете в java.util. Классы для ввода и вывода входят в пакет java.io, а классы для работы в сети – в java.net. Некоторые их этих пакетов содержат подпакеты. Так, например, java.lang содержит два специализированных пакета java.lang.reflect и java.lang.ref, а java.util содержит подпакет java.util.zip, который включает классы для работы с ZIPархивами.

Каждый класс имеет как простое имя, данное ему в определении, так и полное имя, включающее имя пакета, в который он входит. Например, класс String является частью пакета java.lang, а его полное имя – java.lang.String.

Структура пакетов в точности отображает структуру файловой системы. Все файлы с исходными кодами (java-класс) и байт-кодами (расширением class), образующие один пакет, хранятся в одном каталоге файловой системы. Подпакеты образуют подкаталоги этого каталога. Каждый пакет создает единое пространство имен namespace. Это означает, что все имена классов и интерфейсов в пакете должны быть уникальны. Имена в разных пакетах могут совпадать, но это будут разные программные модули. Организация классов в виде пакетов позволяет избежать конфликта имен между классами. В пакете дублирование имен классов не допускается. Принадлежность класса к пакету позволяет гарантировать однозначность имен.

Чтобы указать, что класс принадлежит определенному пакету, следует использовать директиву package, после которой указывается наименование (путь) пакета :

package company.common; public class HelloWorld < public static void main(String[] args)< System.out.println ("Привет, мир!"); >>

В данном примере класс HelloWorld располагается в пакете company.common. Физически это директория «$/company/common». При создании класса в среде разработки IDE (например, Eclipse) следует указать наименование пакета, тогда IDE самостоятельно при необходимости создаст каталог на жестком диске и разместит новый класс в этом каталоге.

Можно package в классе не определять. В этом случае класс будет находиться в пакете по умолчанию, который не имеет имени «$», т.е. класс будет располагаться в корневой директории исходных кодов проекта.

Наименование пакета может быть любым, но необходимо соблюдать его уникальность в проекте. Соглашение «Code Conventions» рекомендует записывать имена пакетов строчными буквами. Тогда они не будут совпадать с именами классов, которые, по соглашению, начинаются с прописной буквы.

Стандартная библиотека Java API включает сотни классов. Каждый программист в ходе работы создает десятки своих классов. Множество классов быстро увеличивается. Java позволяет отдельные классы, решающие определенную задачу (или несколько задач), объединять в библиотеки классов в виде архивов jar. Но эти библиотеки классов, кроме стандартных, не являются частью языка java.

Импорт пакетов и классов, import

Для использования класса в приложении, его следует подключить. Так расположенный в пакете java.util класс Scanner можно подключить следующим способом :

java.util.Scanner in = new java.util.Scanner(System.in);

В этом примере при определении/создании нового объекта был указыван пакет (полный путь к файлу). Однако данный подход не всегда удобен, и в качестве альтернативы можно импортировать пакеты и классы в приложение с помощью директивы import, которая указывается после директивы package :

package company.common; import java.util.Scanner; public class HelloWorld < public static void main(String[] args)< Scanner in = new Scanner(System.in); >>

Директива import указывается в самом начале кода, после чего идет имя подключаемого класса (класс Scanner в примере).

В примере был подключен только один класс. Однако пакет java.util содержит большое количество разных классов. И чтобы не подключать по отдельности каждый класс, можно сразу подключить весь пакет :

import java.util.*; // импорт всех классов из пакета java.util

Теперь можно использовать любой класс из пакета java.util.

Возможна ситуация, когда используется два класса с одинаковым наименованием, но из разных пакетов. Это относится, например, к классам Date, которые имеются в пакете java.util и в пакете java.sql, или классам List пакетов java.util и java.awt. И если необходимо одновременно использовать оба эти класса, то необходимо указывать полный путь к классам в пакете :

java.util.Date udate = new java.util.Date(); java.sql.Date sdate = new java.sql.Date();

Следует сказать, что основные классы из пакета java.lang (например, String) подключаются автоматически и не требуют «импортирования».

Статический импорт классов, import static

В java можно использовать статический импорт. Для этого вместе с директивой import используется модификатор static :

package company.common; import static java.lang.Math.*; import static java.lang.System.*; public class HelloWorld < public static void main(String[] args) < double result = sqrt(20); out.println(result); >>

В примере определяется статический импорт классов System и Math, которые имеют статические методы. Определение статического импорта позволяет использовать статические методы без названия класса. В примере статическая функция sqrt(20) (можно и Math.sqrt(20)), возвращает квадратный корень числа. То же самое относится и к классу System, в котором определен статический объект out, поэтому можно его использовать без указания класса, если выполнен статический импорт класса System.

Пример использования классов разных пакетов

Рассмотрим простенький проект PackageExample, включающий 3 java-класса. Два java-класса располагаются в одном пакете «ru.java.online», а третий — в другом «ru.java.online.classes». Структура проекта представлена на следующем скриншоте:

Листинг базового класса, BaseClass.java

Базовый класс включает 2 поля (id, name) и методы get/set. В конструкторе значения полей инициализируется.

package ru.java.online; public class BaseClass < private String protected String name = null; public BaseClass() < this.id = "default"; this.name = "Наименование не определено"; >public String getId() < return id; >public void setId(String id) < this.id = id; >public String getName() < return name; >public void setName(String name) < this.name = name; >@Override public String toString() < return this.getClass().getName() + "\n\t"; > >

Переопределенная функция toString() возвращает наименование класса и значение полей.

Листинг наследника, Inheritor.java

Класс Inheritor.java наследует свойства базового класса BaseClass.java. Поскольку классы располаются в разных пакетах, то базовый класс необходимо импортировать.

package ru.java.online.classes; import ru.java.online.BaseClass; public class Inheritor extends BaseClass < public Inheritor() < this.name = "Наследник"; this.setId("Первый"); >>
Листинг основного класса, MainPackage.java

Основной класс включает статический метод main. Поскольку данный класс не «видит» наследника, то его приходится импортировать.

package ru.java.online; import ru.java.online.classes.Inheritor; public class MainPackage < public MainPackage() < BaseClass bc = new BaseClass(); Inheritor ir = new Inheritor(); System.out.println (bc.toString()); System.out.println (ir.toString()); >public static void main(String[] args) < new MainPackage(); System.exit(0); >>

Результат выполнения данной программы выводится в консоль в следующем виде :

ru.java.online.BaseClass: ru.java.online.classes.Inheritor:

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

Говоря о полном наименовании класса следует отметить, что оно включает не только наименование пакета и наименование класса, но также и класс-загрузчик classloader. Подробно о классах-загрузчиках можно почитать здесь.

Использование компонентов данных

В данном разделе рассмотрены практические примеры работы с компонентами данных.

Декларативное использование

Обычно компоненты данных определяются и привязываются к визуальным компонентам декларативно в XML-дескрипторе экрана. Если экран для сущности создан с помощью Studio, можно увидеть корневой элемент , содержащий объявления компонентов данных.

Ниже приведен пример компонентов данных на экране деталей сущности User , который содержит to-one ссылку на Department и to-many ссылку на сущность UserStep :

 (1) (2) (3)     (4) (5)  (6)  (7)  
1 Корневой элемент data определяет экземпляр DataContext.
2 Контейнер InstanceContainer сущности User .
3 Опциональный атрибут fetchPlan определяет граф объектов, который должен быть жадно загружен из базы данных.
4 InstanceLoader , загружающий экземпляры сущности User .
5 Контейнер CollectionPropertyContainer для вложенной сущности UserStep . Этот контейнер привязан к атрибуту-коллекции User.steps .
6 Контейнер CollectionContainer для сущности Department . Он может быть использован как источник элементов выпадающего списка выбора Department .
7 CollectionLoader , загружающий экземпляры сущности Department по определенному запросу.

Заданные выше контейнеры данных могут использоваться в визуальных компонентах следующим образом:

 (1) (2)   (3)  (4)     
1 Отдельные поля имеют атрибуты dataContainer и property .
2 Компонент formLayout распространяет свой dataContainer на все вложенные поля, поэтому они требуют только указания атрибута property .
3 Компонент entityComboBox имеет атрибут itemsContainer для получения списка опций.
4 У таблицы dataGrid есть только атрибут dataContainer .

Программное использование

Компоненты данных можно создавать и использовать программно.

В следующем примере мы создадим экран деталей с теми же компонентами данных и визуальными компонентами, которые мы определяли декларативно в предыдущем примере, только на Java без XML-дескриптора.

@Route(value = "users2/:id", layout = MainView.class) @ViewController("User.detail2") public class UserDetailViewProgrammatic extends StandardDetailView (1) @Autowired private UiComponents uiComponents; @Autowired private FetchPlans fetchPlans; @Autowired private Metadata metadata; private InstanceContainer userDc; private InstanceLoader userDl; private CollectionPropertyContainer stepsDc; private CollectionContainer departmentsDc; private CollectionLoader departmentsDl; @Subscribe public void onInit(InitEvent event) < createDataComponents(); createUiComponents(); >private void createDataComponents() (2) userDc = dataComponents.createInstanceContainer(User.class); userDl = dataComponents.createInstanceLoader(); userDl.setContainer(userDc); (3) userDl.setDataContext(dataContext); (4) FetchPlan userFetchPlan = fetchPlans.builder(User.class) .addFetchPlan(FetchPlan.BASE) .add("department", FetchPlan.BASE) .add("steps", FetchPlan.BASE) .add("steps.step", FetchPlan.BASE) .build(); userDl.setFetchPlan(userFetchPlan); stepsDc = dataComponents.createCollectionContainer( UserStep.class, userDc, "steps"); (5) departmentsDc = dataComponents.createCollectionContainer(Department.class); departmentsDl = dataComponents.createCollectionLoader(); departmentsDl.setContainer(departmentsDc); departmentsDl.setDataContext(dataContext); departmentsDl.setQuery("select e from Department e"); (6) departmentsDl.setFetchPlan(FetchPlan.BASE); > private void createUiComponents() < TypedTextFieldusernameField = uiComponents.create(TypedTextField.class); usernameField.setValueSource(new ContainerValueSource<>(userDc, "username")); (7) getContent().add(usernameField); FormLayout formLayout = uiComponents.create(FormLayout.class); getContent().add(formLayout); TypedTextField firstNameField = uiComponents.create(TypedTextField.class); firstNameField.setValueSource(new ContainerValueSource<>(userDc, "firstName")); formLayout.add(firstNameField); TypedTextField lastNameField = uiComponents.create(TypedTextField.class); lastNameField.setValueSource(new ContainerValueSource<>(userDc, "lastName")); formLayout.add(lastNameField); EntityComboBox departmentField = uiComponents.create(EntityComboBox.class); departmentField.setValueSource(new ContainerValueSource<>(userDc, "department")); departmentField.setItems(departmentsDc); (8) formLayout.add(departmentField); DataGrid dataGrid = uiComponents.create(DataGrid.class); dataGrid.addColumn(metadata.getClass(UserStep.class).getPropertyPath("step.name")); dataGrid.setItems(new ContainerDataGridItems<>(stepsDc)); (9) getContent().add(dataGrid); getContent().expand(dataGrid); Button okButton = uiComponents.create(Button.class); okButton.setText("OK"); okButton.addClickListener(clickEvent -> closeWithSave()); getContent().add(okButton); Button cancelButton = uiComponents.create(Button.class); cancelButton.setText("Cancel"); cancelButton.addClickListener(clickEvent -> closeWithDiscard()); getContent().add(cancelButton); > @Override protected InstanceContainer getEditedEntityContainer() (10) return userDc; > @Subscribe protected void onBeforeShow(BeforeShowEvent event) (11) userDl.load(); departmentsDl.load(); > >
1 DataComponents — это фабрика для создания компонентов данных.
2 Регистрируем в экране экземпляр DataContext , чтобы обеспечить работу стандартного действия сохранения экрана.
3 Загрузчик userDl загружает данные в контейнер userDc .
4 Загрузчик userDl помещает загруженные сущности в data context для отслеживания изменений.
5 stepsDc создается как контейнер свойства.
6 Определяем запрос для загрузчика departmentsDl .
7 ContainerValueSource используется для связи одиночных полей с контейнерами данных.
8 CollectionContainer напрямую используется для предоставления списка элементов для полей выбора.
9 ContainerDataGridItems используется для связи таблиц dataGrid с контейнерами.
10 Переопределяем getEditedEntityContainer() , чтобы указать контейнер вместо аннотации @EditedEntityContainer .
11 Загружаем данные перед отображением экрана. Идентификатор редактируемой сущности будет автоматически передан в загрузчик userDl .

Зависимости между компонентами данных

Иногда требуется загружать и отображать данные, которые зависят от других данных в том же экране. К примеру, на скриншоте ниже таблица слева отображает список пользователей (сущность User ), а таблица справа – список шагов онбординга (сущность UserStep ) выбранного сотрудника. Список справа обновляется каждый раз, когда меняется выбранный элемент в таблице слева.

dependent tables

В этом примере сущность User содержит атрибут steps , который является коллекцией с отношением one-to-many. Самый простой способ реализации такого экрана – загружать список пользователей с фетч-планом, содержащим атрибут steps , и использовать контейнер свойств для работы со списком зависимых строк UserStep . Затем связать левую таблицу с родительским контейнером, а правую – с контейнером свойства.

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

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

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

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

   (1)  (2)  (3)   (4)      (5)        
1 Главный контейнер и загрузчик.
2 Зависимый контейнер и загрузчик.
3 Фасет DataLoadCoordinator здесь не используется, поэтому загрузчики нужно вызвать программно в контроллере.
4 Главная таблица.
5 Зависимая таблица.
@Route(value = "users-with-steps", layout = MainView.class) @ViewController("UserWithStepsListView") @ViewDescriptor("user-with-steps-list-view.xml") @LookupComponent("usersTable") @DialogMode(width = "50em", height = "37.5em") public class UserWithStepsListView extends StandardListView  < @ViewComponent private CollectionLoaderusersDl; @ViewComponent private CollectionLoader userStepsDl; @Subscribe public void onBeforeShow(final BeforeShowEvent event) (1) > @Subscribe(id = "usersDc", target = Target.DATA_CONTAINER) public void onUsersDcItemChange(final InstanceContainer.ItemChangeEvent event) (2) userStepsDl.load(); > >
1 Главный загрузчик вызывается обработчиком BeforeShowEvent .
2 В обработчике ItemChangeEvent главного контейнера передается параметр в зависимый загрузчик и вызывается его загрузка.
Фасет DataLoadCoordinator позволяет устанавливать связи между компонентами данных декларативно без написания кода на Java.

Специализированная сортировка

Сортировка таблиц по атрибутам сущности в UI производится объектом типа CollectionContainerSorter , который устанавливается для CollectionContainer. Стандартная реализация сортирует данные в памяти, если загруженный список умещается на одной странице, или посылает запрос с соответствующим «order by» в базу данных. Выражение «order by» формируется бином JpqlSortExpressionProvider .

Некоторые атрибуты могут потребовать специальной реализации сортировки. Ниже рассматривается простой пример: предположим, в сущности Department есть атрибут num типа String , но на самом деле атрибут хранит только числовые значения. Поэтому необходимо иметь порядок сортировки для чисел: 1 , 2 , 3 , 10 , 11 . Стандартный механизм сортировки в данном случае выдаст порядок 1 , 10 , 11 , 2 , 3 .

Сначала создайте наследника класса CollectionContainerSorter для сортировки в памяти:

package com.company.onboarding.app; import com.company.onboarding.entity.Department; import io.jmix.core.Sort; import io.jmix.core.metamodel.model.MetaClass; import io.jmix.core.metamodel.model.MetaPropertyPath; import io.jmix.flowui.model.BaseCollectionLoader; import io.jmix.flowui.model.CollectionContainer; import io.jmix.flowui.model.impl.CollectionContainerSorter; import io.jmix.flowui.model.impl.EntityValuesComparator; import org.springframework.beans.factory.BeanFactory; import java.util.Comparator; import java.util.Objects; public class CustomCollectionContainerSorter extends CollectionContainerSorter < public CustomCollectionContainerSorter(CollectionContainercontainer, BaseCollectionLoader loader, BeanFactory beanFactory) < super(container, loader, beanFactory); >@Override protected Comparator createComparator(Sort.Order sortOrder, MetaClass metaClass) < MetaPropertyPath metaPropertyPath = Objects.requireNonNull( metaClass.getPropertyPath(sortOrder.getProperty())); if (metaPropertyPath.getMetaClass().getJavaClass().equals(Department.class) && "num".equals(metaPropertyPath.toPathString())) < boolean isAsc = sortOrder.getDirection() == Sort.Direction.ASC; return Comparator.comparing((Department e) ->e.getNum() == null ? null : Integer.valueOf(e.getNum()), new EntityValuesComparator<>(isAsc, metaClass, beanFactory)); > return super.createComparator(sortOrder, metaClass); > >

Создайте сортировщик в нужном экране:

public class DepartmentListView2 extends StandardListView  < @ViewComponent private CollectionContainerdepartmentsDc; @ViewComponent private CollectionLoader departmentsDl; @Autowired private BeanFactory beanFactory; @Subscribe public void onInit(final InitEvent event)

Если же специализированная сортировка должна являться глобальной, то создайте собственную фабрику, которая будет инстанциировать сортировщик для всей системы:

package com.company.onboarding.app; import io.jmix.flowui.model.BaseCollectionLoader; import io.jmix.flowui.model.CollectionContainer; import io.jmix.flowui.model.Sorter; import io.jmix.flowui.model.SorterFactory; import org.springframework.lang.Nullable; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @Primary @Component public class CustomSorterFactory extends SorterFactory < @Override public Sorter createCollectionContainerSorter(CollectionContainer container, @Nullable BaseCollectionLoader loader) < return new CustomCollectionContainerSorter(container, loader, beanFactory); >>

Кроме того, можно создать собственную реализацию JpqlSortExpressionProvider для сортировки на уровне базы данных:

package com.company.onboarding.app; import com.company.onboarding.entity.Department; import io.jmix.core.metamodel.model.MetaPropertyPath; import io.jmix.data.impl.DefaultJpqlSortExpressionProvider; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @Primary @Component public class CustomSortExpressionProvider extends DefaultJpqlSortExpressionProvider < @Override public String getDatatypeSortExpression(MetaPropertyPath metaPropertyPath, boolean sortDirectionAsc) < if (metaPropertyPath.getMetaClass().getJavaClass().equals(Department.class) && "num".equals(metaPropertyPath.toPathString())) < return String.format("CAST(.%s BIGINT)", metaPropertyPath); > return String.format(".%s", metaPropertyPath); > >

This page was built using the Antora default UI.

The source code for this UI is licensed under the terms of the MPL-2.0 license.

Package com company что это java

Как правило, в Java классы объединяются в пакеты. Пакеты позволяют организовать классы логически в наборы. По умолчанию java уже имеет ряд встроенных пакетов, например, java.lang , java.util , java.io и т.д. Кроме того, пакеты могут иметь вложенные пакеты.

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

Чтобы указать, что класс принадлежит определенному пакету, надо использовать директиву package , после которой указывается имя пакета:

package название_пакета;

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

Классы необязательно определять в пакеты. Если для класса пакет не определен, то считается, что данный класс находится в пакете по умолчанию, который не имеет имени.

Например, создадим в папке для исходных файлов каталог study . В нем создадим файл Program.java со следующим кодом:

package study; public class Program < public static void main(String[] args) < Person kate = new Person("Kate", 32); kate.displayInfo(); >> class Person < String name; int age; Person(String name, int age)< this.name = name; this.age = age; >void displayInfo() < System.out.printf("Name: %s \t Age: %d \n", name, age); >>

Директива package study в начале файла указывает, что классы Program и Person, которые здесь определены, принадлежат пакету study.

Когда мы работаем в среде разработки, например, в Netbeans, то IDE берет на себя все вопросы компиляции пакетов и входящих в них файлов. Соответственно нам достаточно нажать на кнопку, и все будет готово. Однако если мы компилируем программу в командной строке, то мы можем столкнуться с некоторыми трудностями. Поэтому рассмотрим этот аспект.

Для компиляции программы вначале в командной строке/терминале с помощью команды cd перейдем к папке, где находится каталог study.

cd C:\java

Например, в моем случае это каталог C:\java (то есть файл с исходным кодом расположен по пути C:\java\study\Program.java).

Для компиляции выполним команду

javac study\Program.java

После этого в папке study появятся скомпилированные файлы Program.class и Person.class. Для запуска программы выполним команду:

java study.Program

Компиляция пакетов в Java

Импорт пакетов и классов

Если нам надо использовать классы из других пакетов, то нам надо подключить эти пакеты и классы. Исключение составляют классы из пакета java.lang (например, String ), которые подключаются в программу автоматически.

Например, знакомый по прошлым темам класс Scanner находится в пакете java.util , поэтому мы можем получить к нему доступ следующим способом:

java.util.Scanner in = new java.util.Scanner(System.in);

То есть мы указываем полный путь к файлу в пакете при создании его объекта. Однако такое нагромождение имен пакетов не всегда удобно, и в качестве альтернативы мы можем импортировать пакеты и классы в проект с помощью директивы import , которая указывается после директивы package:

package study; import java.util.Scanner; // импорт класса Scanner public class Program < public static void main(String[] args) < Scanner in = new Scanner(System.in); >>

Директива import указывается в самом начале кода, после чего идет имя подключаемого класса (в данном случае класса Scanner).

В примере выше мы подключили только один класс, однако пакет java.util содержит еще множество классов. И чтобы не подключать по отдельности каждый класс, мы можем сразу подключить весь пакет:

import java.util.*; // импорт всех классов из пакета java.util

Теперь мы можем использовать любой класс из пакета java.util.

Возможна ситуация, когда мы используем два класса с одним и тем же названием из двух разных пакетов, например, класс Date имеется и в пакете java.util , и в пакете java.sql . И если нам надо одновременно использовать два этих класса, то необходимо указывать полный путь к этим классам в пакете:

java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date();

Статический импорт

В java есть также особая форма импорта - статический импорт. Для этого вместе с директивой import используется модификатор static :

package study; import static java.lang.System.*; import static java.lang.Math.*; public class Program < public static void main(String[] args) < double result = sqrt(20); out.println(result); >>

Здесь происходит статический импорт классов System и Math. Эти классы имеют статические методы. Благодаря операции статического импорта мы можем использовать эти методы без названия класса. Например, писать не Math.sqrt(20) , а sqrt(20) , так как функция sqrt() , которая возвращает квадратный корень числа, является статической. (Позже мы рассмотрим статические члены класса).

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *