Java как использовать класс из другого файла

Обновлено: 06.07.2024

Эта статья посвящена нескольким наиболее часто используемым методам чтения файла на Java.

  1. Файлы.строки , возвращают поток ( Java 8)
  2. Files.ReadString , возвращает Строка (Java 11), максимальный размер файла 2G.
  3. Files.ReadAllBytes , возвращает байт[] (Java 7), максимальный размер файла 2G.
  4. Files.ReadAllLines , возвращает Список<Строка> ( Java 8)
  5. BufferedReader , классический старый друг (Java 1.1 -> навсегда)
  6. Сканер (Java 1.5)

Новая Java 8 Files.lines хорошо работает при чтении небольших или больших текстовых файлов, возвращает Поток (гибкий тип и поддержка параллельных), автоматически закрывает ресурсы и содержит одну строку чистого кода.

В современной Java 8+ мы должны использовать Files.lines для чтения текстового файла.

Примечание В двух словах, нет большой разницы в чтении небольших файлов, просто вкус возвращаемого типа. Для чтения в большом файле выберите Java 8 Files.lines для потоковых и параллельных функций или классический БуферизоВанный читатель .

Текстовый Файл

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

1. Файлы.строки ( Java 8)

1.1 В этом примере используется Java 8 Files.lines для чтения вышеупомянутого файла в Поток и печати его строка за строкой. Кроме того, Files.lines поможет автоматически закрыть открытый ресурс (файл); нам не нужно заключать код в try-with-resources .

1.2 Для чтения в небольшом текстовом файле мы можем использовать собрать легко преобразовать поток в Список<Строка> .

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

1.4 Распространенной ошибкой является прямое преобразование большого Потока в Список , и это приведет к java.lang. Ошибка из памяти: Пространство кучи Java если размер потока больше, чем размер кучи запущенной JVM.

1.5 Последний, lines.foreach , не сохраняет порядок строк, попробуйте lines.forEachOrdered если мы хотим сохранить порядок.

2. Файлы.Строка чтения (Java 11)

2.1 Это Files.ReadString() считывает файл в строку, и если размер файла для чтения превышает 2G, он выдает java.lang. Ошибка из памяти: Требуемый размер массива слишком велик .

2.2 Просмотрите исходный код, новую Java 11 ReadString , внутренне используйте существующую Java 7 ReadAllBytes для чтения файла в байт[] и JLA.новая строка Без ответа для преобразования байта[] обратно в строку.

3. Файлы.ReadAllBytes (Java 7)

3.1 В этом примере используется Files.ReadAllBytes для чтения файла в массив байтов байт [] , если размер файла для чтения превышает 2G, он будет выбрасывать java.lang. Ошибка из памяти: Требуемый размер массива слишком велик .

4. Файлы.Строки для чтения (Java 8)

4.1 В этом примере используется Files.ReadAllLines чтобы прочитать файл в Список<Строка> , если размер файла больше, чем размер кучи запущенной JVM, он выбросит java.lang. Ошибка из памяти: Пространство кучи Java .

5. БуферизоВанный читатель (Java 1.1)

5.1 Классический и старый друг, BufferedReader пример, хорошо работает при чтении небольших и больших файлов, а размер буфера по умолчанию (8 кб) достаточно велик для большинства целей.

5.2 Мы можем указать размер буфера.

5.3 В Java 8 мы можем использовать новый Files.newBufferedReader для создания BufferedReader .

Просмотрите исходный код, ничего особенного.

Прочтите это – Java Как читать файл с помощью BufferedReader

5.4 Для справки, классическая попытка поймать, наконец, закрыть открытый файл вручную.

6. Сканер (Java 1.5)

6.1 В классе Сканер функция разделитель по-прежнему полезна для чтения и фильтрации небольшого файла. Java 9 и Java 10 добавили новые методы, такие как найдите все и конструкторы для улучшения класса Сканер . Однако для чтения в большом файле этот класс Scanner работает медленно по сравнению с BufferedReader .

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

Как происходит загрузка классов?

Для того, чтобы найти класс по имени когда вы его вызываете, в Java существует стандартный загрузчик классов. Он оперирует понятием classpath. Список classpath — это набор путей, где следует искать файлы классов. Каждый classpath может указывать как на директорию, так и на так называемый jar-файл (зазипованная директория со скомпилированными .class'ами и разрешением .jar, типа «йА java-archive!»). По умолчанию в classpath входят файлы стандартных библиотек и директория, из которой вы вызвали саму Java. Именно таким образом был найден класс HelloWorld — java нашла файл HelloWorld.class и запустила в нём метод main. Собственно, так и работают большинство программ, даже самых сложных. Всё начинается с одного main'а…

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

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

Организация кода

Если вы пишете свои первые маленькие примерчики и вам лень создавать иерархию классов — пусть, это ваше право. Но помните, в серьёзном проекте вы всегда должны будете разложить свои классы по пакетам. Обычно корневые пакеты создаются такими, чтобы ясно давать понять кто автор кода, и к чему он относится.
Например:
ru.vasiapupkin.photomaker выбирается корневым пакетом
ru.vasiapupkin.photomaker.core сюда мы пишем классы отвечающие за логику
ru.vasiapupkin.photomaker.visual сюда, допустим, все наши окошки приложения

и так далее.
Чтобы создать класс
ru.vasiapupkin.photomaker.Starter
вы должны:
создать файл Starter.java в папке ru/vasiapupkin/photomaker/
прописать в нём первой строчкой (точнее говоря, до импортов)
package ru.vasiapupkin.photomaker;

Коллижн

«А что будет, если у нас будет два класса с одним именем?», — спросите вы. «Смотрите», — отвечу я.
Допустим вы решили что вы умнее джавы и создали свой класс строки — String. Но вот проблема, у нас же уже есть такой!
Значит, вам придётся положить свой класс в пакет, скажем ru.vp.stuff и обращаться к нему так: ru.vp.stuff.String.
Именно поэтому не рекомендуется класть классы прямо в корень classpath — таким образом вы роете себе дорогу к несовместимости, ведь Java требует, чтобы каждый класс определялся однозначно. Именно поэтому нельзя написать так:
import ru.vp.SuperClass;
import ru.mashka.SuperClass;
За это вас накажет компилятор, потому что он не будет знать, какой из них использовать.
Мораль: правильно выбирайте и имя класс и имя пакета.

Погоняем?

Давайте улучшим первое приложение. Эх, классика интернета… Создадим апплет.

Эх, может быть апплетами.

import java.applet.Applet ;
import java.awt.Graphics ;

public class HelloWorld extends Applet

public void paint( Graphics g) g.drawString( "Hello World" ,15,15);
>

>

* This source code was highlighted with Source Code Highlighter .

Так, что у нас тут? Импортировано 2 класса, один из них — стандартный пустой апплет, который мы будем расширять. Второй — Graphics. Graphics — это понятие из библиотеки AWT. Кстати, небольшой экскурс. AWT (Abstract Window Toolkit) входил ещё в первую Java и был предназначен для многих задач, связанных в основном с отображением.
Так вот, объект типа Graphics позволяет нам рисовать на себе всякую муру типа строк, линий, кружочков и прочего. В данном примере мы написали строчку с отступом.
Метод paint здесь написан не от балды — он перекрывает аналогичный метод класса Applet, и когда java будет перерисовывать этот конкретный апплет, она вызовет этот метод.

Посмотреть на наш апплет достаточно просто — пишем небольшой HTML:

< body >
< applet code ="HelloWorld.class" codebase ="file:///home/devgru/" width ="150" height ="30" ></ applet >
</ body >

* This source code was highlighted with Source Code Highlighter .

… а может приложением.

Давайте попробуем сделать HelloWorld в standalone-приложении.

import java.awt.* ;
import javax.swing.* ;
public class HelloWorld extends JFrame

public static void main( String [] args) new HelloWorld();
>

add( new JLabel( "Hello world" ));
setSize(200,200);
setVisible( true );
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
>
>

* This source code was highlighted with Source Code Highlighter .

Здесь мы полностью импортируем основные классы пакетов Swing и AWT. Swing — более поздняя чем AWT библиотека, сейчас именно она обеспечивает отображение основной части графического интерфейса для Java-приложений.
Итак, в main мы просто создаём экземпляр класса HelloWorld.
Сейчас наш класс наследуется от класса JFrame. Это класс из Swing, он представляет собой окно, которое отображается пока не будет закрыто.
Блок <. >— это «общий конструктор». Он добавляется к любому конструктору нашего класса. Так как у нас нет ни одного — он добавляется к пустому конструктору без параметров, который создаётся на лету, если у класса нет ни одного.
Мы добавляем на окно новый объект типа JLabel (т.е. надпись), затем устанавливаем окну размеры и отображаем его. Последняя строчка нужна, чтобы выполнение приложения закончилось, когда будет закрыто окно. Таким образом, вы можете быть уверены что после закрытия окна у вас в памяти не останется висеть ваше приложение.
Запускать его нужно точно так же как и прошлое: пишем, компилируем, запускаем.

А может и сервлетами? Наверное, потом.

Когда отпишетесь — станет ясно, куда копать дальше. Всем спасибо за внимание.

Итак, у меня есть этот файл класса ( DateFirstTry.java ) и главный файл, в котором запускается программа.

Итак, они объяснили, как мне создать методы makeItNewYears и yellIfNewYears , но не объяснили, как их вызывать в основном коде. Я что-то пробовал, и DateFirstTry makeItNewYears; - единственное, что не выдает ошибок, но и не дает никаких результатов.

Надеюсь, кто-нибудь сможет мне с этим помочь!

2 ответа

Поскольку это методы экземпляра, вам сначала нужно создать экземпляр DateFirstTry , как, например, вы сделали с date1 :

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

У класса может быть состояние и поведение. Состояние - это данные. В вашем классе DateFirstTry это переменные, влияющие на состояние:

Методы представляют собой конкретное поведение или набор операций. Поведение класса выполняет действие над данными. Это может или не может изменить состояние класса при выполнении этих действий. Например,

Метод makeItNewYears() изменяет состояние, поскольку он изменяет значение month и day . С другой стороны,

Метод выполняет какое-то действие, но не меняет состояние. Он просто использует данные, но не меняет их значение.

Объект является экземпляром этого класса. Если Person является классом, то John является экземпляром этого класса. У класса может быть любое количество экземпляров. Каждый экземпляр имеет собственное состояние и все поведение, определенное в классе. Чтобы создать экземпляр, вы используете следующий синтаксис:

date1 и date2 - два экземпляра / объекта этого класса. У них одинаковые свойства month , day и year . Но их значения могут быть разными для каждого объекта. Для вызова метода вам необходимо вызвать его в экземпляре. У нас есть два экземпляра date1 и date2 . Для вызова writeOutput() используйте:

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

Каждый объект может выполнять такое поведение.

Проверит, соответствуют ли значения месяца, дня и года date1 Новый год. Если вы вызываете тот же метод, что и:

Пакет подобен каталогу в файловой системе. На самом деле на диске он является каталогом. Все исходные файлы и файлы классов, принадлежащих одному и тому же пакету, находятся в одном каталоге.

Могут содержать подпакеты. Таким образом, могут составлять так называемую структуру пакета, похожую на структуру каталогов. Это дерево пакетов, подпакетов и классов внутри этих классов. Организована как каталоги на вашем жестком диске или как каталоги внутри zip-файла (JAR-файлы).

Вот скриншот примера структуры:

Пример структуры пакета Java

Расширено два пакета подуровня, чтобы вы могли видеть классы внутри. Классы проиллюстрированы с помощью маленького синего круга с буквой C внутри, на скриншоте выше.

Точно так же полное имя класса включает имя его пакета. Например, полное имя класса «Page»:

Создание структуры

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

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

Добавление классов

Чтобы добавить классы, вы должны сделать две вещи:

  1. Поместите исходный файл в каталог, соответствующий пакету, в который вы хотите поместить класс.
  2. Объявите этот класс как часть пакета.

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

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

Соглашения об именах

Пакеты всегда пишутся строчными буквами. В отличие от классов, где первая буква обычно является заглавной.

Импорт

Если класс A должен использовать класс B, вы должны ссылаться на класс B внутри класса A. Если классы A и B находятся в одном и том же пакете, компилятор будет принимать ссылки между двумя классами:

Если классы A и B находятся в одном и том же пакете, проблем с кодом выше нет. Однако, если класс A и B находятся в разных, класс A должен импортировать класс B, чтобы использовать его:

Это первая строка в примере, которая импортирует класс B. В примере предполагается, что класс B находится в пакете с именем anotherpackage.

Если бы класс B находился в подпакете другого пакета, вам пришлось бы перечислить полный путь пакета и подпакета к классу B. Например, если бы класс B находился в пакете anotherpackage.util, то оператор import выглядел бы так:

Импорт всех классов из другого пакета

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

Использование классов через определенное имя

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

Пакетное разделение

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

Разделить на слои

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

Разделить по функциональности приложения

В сочетании с доменным именем структура для пенсионного пакета будет:

Всего три пакета, два вложенных в другие.

Метод «деления по функциональности приложения» имеет тенденцию работать лучше, чем «деление по слоям», поскольку в вашем приложении растет число классов.

Вместо того, чтобы иметь фиксированное количество пакетов слоев, число которых продолжает расти, вы получаете растущее число пакетов функциональности приложения с меньшим количеством классов внутри.

Встроенные

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

Читайте также: