Как я могу создать служебный класс?

Я хочу создать класс с служебными методами, например

public class Util {

   public static void f (int i) {...}

   public static int g (int i, int j) {...}

}

Какой метод создания служебного класса лучше всего?

Стоит ли использовать частный конструктор?

Должен ли я создать служебный класс для абстрактного класса?

Ничего не делать?


person user2693979    schedule 09.08.2014    source источник
comment
при программировании обычно нет лучшего способа что-либо сделать   -  person William Reed    schedule 10.08.2014
comment
Самый простой способ создать служебный класс projectlombok.org/features/experimental/UtilityClass   -  person adimoh    schedule 03.12.2018
comment
Should I do nothing? Как дзен.   -  person awwsmm    schedule 07.12.2018
comment
@WilliamReed На самом деле лучшее зависит от контекста. : D   -  person Sreekanth Karumanaghat    schedule 28.03.2019
comment
@SreekanthKarumanaghat Да, я согласен. мое мнение сильно изменилось с тех пор, как я оставил этот комментарий   -  person William Reed    schedule 28.03.2019
comment
используйте аннотацию projectlombok.org/features/experimental/UtilityClass @UtilityClass из lombok.   -  person user811602    schedule 21.05.2020


Ответы (4)


Для служебного класса, полностью не имеющего состояния в Java, я предлагаю объявить класс public и final и иметь частный конструктор для предотвращения создания экземпляров. Ключевое слово final предотвращает подклассы и может повысить эффективность во время выполнения.

Класс должен содержать все static методы и не должен объявляться abstract (поскольку это означало бы, что класс не является конкретным и должен быть каким-то образом реализован).

Классу следует дать имя, соответствующее его набору предоставленных утилит (или «Утилита», если класс должен предоставлять широкий диапазон утилит без категорий).

Класс не должен содержать вложенный класс, если только вложенный класс не должен быть служебным классом (хотя эта практика потенциально сложна и ухудшает читаемость).

У методов в классе должны быть соответствующие имена.

Методы, используемые только самим классом, должны быть закрытыми.

Класс не должен иметь каких-либо нефинальных / нестатических полей класса.

Класс также может быть статически импортирован другими классами для улучшения читаемости кода (однако это зависит от сложности проекта).

Пример:

public final class ExampleUtilities {
    // Example Utility method
    public static int foo(int i, int j) {
        int val;

        //Do stuff

        return val;
    }

    // Example Utility method overloaded
    public static float foo(float i, float j) {
        float val;

        //Do stuff

        return val;
    }

    // Example Utility method calling private method
    public static long bar(int p) {
        return hid(p) * hid(p);
    }

    // Example private method
    private static long hid(int i) {
        return i * 2 + 1;
    }
}

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

person initramfs    schedule 09.08.2014
comment
Подчеркну, что качественная документация означает полные комментарии JavaDoc, а не комментарии к коду. - person Brian Kelly; 03.05.2017
comment
@initramfs, это хороший ответ, но не могли бы вы адаптировать свой пример в соответствии с тем, что вы пишете, чтобы сделать его согласованным !? - person karlihnos; 21.12.2017
comment
Возможно, самое главное, чтобы документация по каждому методу была точной и описательной. Скорее всего, методы этого класса будут использоваться очень часто, и хорошо иметь качественную документацию, дополняющую код. Обновите комментарии javadoc для приведенного выше кода. См. oracle.com/technical-resources/articles/java/javadoc -tool.html - person razvanone; 01.04.2021

По словам Джошуа Блоха (Эффективная Java), вы должны использовать частный конструктор, который всегда генерирует исключение. Это окончательно отговорит пользователя от создания экземпляра класса util.

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

person michaldo    schedule 09.08.2014
comment
Я не понял. Зачем вам нужно генерировать исключение в частном конструкторе, если он является частным и класс не будет создан, поэтому исключение никогда не будет сгенерировано? - person Johnny Five; 14.08.2019
comment
@JohnnyFive private-constructor-throwing-exception - это концепция блока Джошуа, призванная обнародовать разработчиками, читающими код, что они НЕ должны создавать никаких экземпляров. - person michaldo; 16.02.2020
comment
@JohnnyFive должно быть выброшено исключение или даже AssertionError, потому что, используя отражение, вы все равно можете получить доступ к частному конструктору. Выдавая исключение или ошибку, вы можете гарантировать, что ни один экземпляр класса не может быть создан. - person Felix S; 09.06.2020
comment
@JohnnyFive Из книги AssertionError не является строго обязательным, но он обеспечивает страховку на случай, если конструктор будет случайно вызван из класса. - person Leponzo; 05.04.2021

Я бы сделал класс final и каждый метод был бы static.

Таким образом, класс не может быть расширен, а методы могут быть вызваны Classname.methodName. Если вы добавляете участников, убедитесь, что они работают потокобезопасно;)

person duffy356    schedule 09.08.2014

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

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

person Sergey Kalinichenko    schedule 09.08.2014