Ответ
Модификатор доступа по умолчанию (также известный как package-private) применяется в Java, когда перед членом класса (полем, методом, конструктором) или самим классом не указан явно ни один из модификаторов: public, protected, private.
Его единственное правило: доступ разрешен только классам, находящимся в одном и том же пакете (package). Классы из других пакетов, даже если они являются наследниками, не видят такие члены.
Практическое применение в организации тестов: Этот модификатор часто используется для создания вспомогательных (helper) классов или методов, которые нужны для внутренней работы компонентов внутри пакета, но не должны быть частью публичного API, доступного другим частям приложения или внешним библиотекам.
// Пакет основного приложения: com.myapp.service
package com.myapp.service;
public class PaymentProcessor {
// Публичный метод — часть API
public PaymentResult process(PaymentRequest request) {
validateRequest(request); // Внутренний вызов package-private метода
String id = generateInternalId(); // Внутренний вызов package-private метода
// ... основная логика
return new PaymentResult(id, Status.SUCCESS);
}
// Package-private метод для валидации. Виден только в этом пакете.
void validateRequest(PaymentRequest request) {
if (request.amount() <= 0) {
throw new InvalidPaymentException("Amount must be positive");
}
}
// Package-private метод для генерации ID. Виден только в этом пакете.
String generateInternalId() {
return "PAY-" + System.currentTimeMillis();
}
}
// Вспомогательный класс в ТОМ ЖЕ пакете. Он package-private (без модификатора).
class PaymentTestHelper { // Не 'public', значит, виден только в com.myapp.service
static PaymentRequest createTestRequest(double amount) {
return new PaymentRequest(amount, "USD", "test_customer");
}
}
// Пакет с ТЕСТАМИ: com.myapp.service (Тот же самый пакет!)
package com.myapp.service; // Тесты в том же пакете
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class PaymentProcessorTest {
@Test
void testProcessWithValidRequest() {
PaymentProcessor processor = new PaymentProcessor();
// Мы можем использовать package-private хелпер, потому что тест в том же пакете.
PaymentRequest testRequest = PaymentTestHelper.createTestRequest(100.0);
PaymentResult result = processor.process(testRequest);
assertNotNull(result.id());
assertEquals(Status.SUCCESS, result.status());
}
@Test
void testValidationForNegativeAmount() {
PaymentProcessor processor = new PaymentProcessor();
PaymentRequest badRequest = PaymentTestHelper.createTestRequest(-50.0);
// Мы тестируем неявно через публичный метод, но знаем, что внутри вызовется package-private validateRequest()
assertThrows(InvalidPaymentException.class, () -> processor.process(badRequest));
}
}
Для QA/тестировщика: Понимание package-private доступа помогает правильно организовать тестовый код. Чтобы протестировать package-private методы напрямую (что иногда полезно для сложной внутренней логики), тестовые классы часто размещают в том же пакете, что и тестируемый код. Это стандартный прием, используемый, например, в проектах Maven/Gradle (тесты в src/test/java с mirrored package structure).