Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Модификатор default (package-private) в Java
default (также называемый package-private) — это уровень видимости членов класса, который подразумевается, когда вы НЕ указываете никакой модификатор доступа. Это не ключевое слово, а неявная видимость.
Что такое default видимость?
Если вы не указываете public, protected или private, то член класса имеет default видимость:
// Класс с default видимостью (видим только в пакете)
class MyClass { // ← no modifier = default (package-private)
int field = 5; // ← default видимость
void method() {} // ← default видимость
}
// Эквивалентно:
public class MyPublicClass { // ← public (видим везде)
public int publicField = 5; // ← public видимость
protected int protectedField; // ← protected видимость
private int privateField; // ← private видимость
/* default */ int defaultField;// ← default видимость (невидим за пределами пакета)
}
Таблица видимости
| Модификатор | Класс | Пакет | Подкласс | Везде |
|---|---|---|---|---|
| public | ✓ | ✓ | ✓ | ✓ |
| protected | ✓ | ✓ | ✓ | ✗ |
| default | ✓ | ✓ | ✗ | ✗ |
| private | ✓ | ✗ | ✗ | ✗ |
Примеры default видимости
1. Default доступ к полям
// Файл: com/example/MyClass.java
package com.example;
public class MyClass {
int defaultField = 10; // default видимость
}
// Файл: com/example/AnotherClass.java
package com.example; // ← ТОЖЕ САМЫЙ ПАКЕТ
public class AnotherClass {
public void test() {
MyClass obj = new MyClass();
System.out.println(obj.defaultField); // ✓ Видно! Один пакет
}
}
// Файл: com/other/ExternalClass.java
package com.other; // ← ДРУГОЙ ПАКЕТ
public class ExternalClass {
public void test() {
MyClass obj = new MyClass();
System.out.println(obj.defaultField); // ✗ ERROR! Не видно вне пакета
}
}
2. Default доступ к методам
// Файл: com/company/Database.java
package com.company;
public class Database {
public void query() {}
void internalQuery() { // default видимость
System.out.println("Internal query");
}
}
// Файл: com/company/Service.java
package com.company; // ← Один пакет
public class Service {
public void execute() {
Database db = new Database();
db.query(); // ✓ Видно (public)
db.internalQuery(); // ✓ Видно (default, но в одном пакете)
}
}
// Файл: com/external/Client.java
package com.external; // ← Другой пакет
public class Client {
public void run() {
Database db = new Database();
db.query(); // ✓ Видно (public)
db.internalQuery(); // ✗ ERROR! Не видно вне пакета
}
}
3. Default для вложенных классов
public class Outer {
public static class PublicNested {} // Видно везде
protected static class ProtectedNested {}
/* default */ static class DefaultNested {} // Видно только в пакете
private static class PrivateNested {} // Видно только в Outer
}
Когда использовать default видимость?
✓ Используй default для:
- Деталей реализации пакета
// Файл: com/myapp/util/Utils.java
package com.myapp.util;
public class Utils {}
// Служебные методы, нужные только в этом пакете
void helperMethod() { } // default
- Внутренних API пакета
// Файл: com/myapp/internal/ConfigBuilder.java
package com.myapp.internal;
public class ConfigBuilder {
Config build() { // default видимость
// Используется только внутри пакета
}
}
- Пакетных (package-scoped) классов
// Файл: com/myapp/core/Engine.java
package com.myapp.core;
class Engine { // default видимость класса
// Видим только в пакете com.myapp.core
}
public class App {
Engine engine = new Engine(); // ✓ Можем создать
}
❌ Не используй default для:
- Public API библиотеки
// ❌ Неправильно
package com.mylib;
class Calculator { // Чужие разработчики не смогут это использовать
int add(int a, int b) { return a + b; }
}
// ✅ Правильно
public class Calculator {
public int add(int a, int b) { return a + b; }
}
- Интерфейсы, которые должны быть публичными
// ❌ Неправильно
interface DataProvider { // Не видим вне пакета
List<Data> getData();
}
// ✅ Правильно
public interface DataProvider {
List<Data> getData();
}
Практический пример: многоуровневая архитектура
// Файл: com/myapp/service/UserService.java
package com.myapp.service;
public class UserService { // ← public: используется везде
public User getUser(Long id) {
return findUserInDatabase(id); // ← default: внутренний метод
}
User findUserInDatabase(Long id) { // default видимость
// Деталь реализации, используется только в пакете
}
}
// Файл: com/myapp/service/EmailService.java
package com.myapp.service; // ← Один пакет с UserService
public class EmailService {
public void sendWelcomeEmail(Long userId) {
UserService userService = new UserService();
User user = userService.findUserInDatabase(userId); // ✓ Видно!
}
}
// Файл: com/myapp/controller/UserController.java
package com.myapp.controller; // ← Другой пакет
public class UserController {
private UserService userService;
public void handleRequest(Long userId) {
User user = userService.getUser(userId); // ✓ Видно (public)
// userService.findUserInDatabase(userId); // ✗ ERROR! default не видно
}
}
Package структура и default видимость
com/
├── myapp/
│ ├── service/ ← Пакет 1
│ │ ├── UserService.java
│ │ └── OrderService.java
│ │
│ └── controller/ ← Пакет 2
│ └── UserController.java
В этой структуре:
- UserService и OrderService видят default методы друг друга (один пакет)
- UserController НЕ видит default методы сервисов (разные пакеты)
Важные правила
1. Класс с default видимостью НЕВИДИМ вне пакета
package com.example;
class MyClass {} // default видимость класса
// В другом пакете:
// MyClass obj = new MyClass(); // ✗ ERROR!
2. Вложенные классы
public class Outer {
// default вложенный класс видим везде, потому что содержится в public классе
// НО только через Outer.Inner
static class Inner {} // default
}
// В другом пакете:
// Outer.Inner obj = new Outer.Inner(); // ✗ ERROR! Inner не видна
3. Интерфейсы с default методами (Java 8+)
public interface MyInterface {
void publicMethod();
default void defaultMethod() { // ← Это НЕ про видимость!
System.out.println("Default implementation");
}
}
// Здесь "default" — это не модификатор доступа,
// а ключевое слово для методов с реализацией в интерфейсе
Лучшие практики
✓ Используй public для public API ✓ Используй protected для расширяемых подклассов ✓ Используй default для пакетной реализации ✓ Используй private для внутренних деталей класса ✓ Минимизируй видимость (Principle of Least Privilege) ✓ По умолчанию пиши private, добавляй видимость только когда нужна
Сравнение всех модификаторов
public class ExampleClass {
public int publicField; // Видно везде
protected int protectedField; // Видно в пакете и подклассах
int defaultField; // Видно только в пакете
private int privateField; // Видно только в классе
}