← Назад к вопросам

Что такое модификатор default?

1.0 Junior🔥 141 комментариев
#ООП#Основы Java

Комментарии (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 для:

  1. Деталей реализации пакета
// Файл: com/myapp/util/Utils.java
package com.myapp.util;

public class Utils {}

// Служебные методы, нужные только в этом пакете
void helperMethod() { }  // default
  1. Внутренних API пакета
// Файл: com/myapp/internal/ConfigBuilder.java
package com.myapp.internal;

public class ConfigBuilder {
    Config build() {  // default видимость
        // Используется только внутри пакета
    }
}
  1. Пакетных (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 для:

  1. 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; }
}
  1. Интерфейсы, которые должны быть публичными
// ❌ Неправильно
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;            // Видно только в классе
}