Правильно делать приватные методы Java статическими или нет? Плюсы и минусы каждого варианта?

1,00
р.
В английской версии видел этот вопрос, но в русской версии не нашел. Часто некоторые программисты используют private static методы, чтобы показать что этот приватный метод не использует никаких переменных и методов класса, другие наоборот против этого подхода так считают его не правильным использованием ООП (речь только о приватных методах класса, не использующих никаких переменных класса и других не статических методов).
То есть, что правильнее по вашему использовать так
public class MyClass { private static void func1() { // со статик ... } }
или так
public class MyClass { private void func1() { // без статик ... } }
?
Я говорил о тех методах, которые не используют (и не могут использовать) поля напрямую, например метод boolean isValid(T str), который вызывается в других методах класса для множества различных объектов, и которые нужны исключительно только для этого класса и выносить их в отдельный Utils класс нет смысла.
Как пример такого метода это hugeCapacity в ArrayList из Oracle JDK 8:
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError() return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE }
P.S. Любые цитаты и ссылки на известных Java авторов очень помогут решить вопрос (скажем, я знаю, что в ArrayList из Oracle JDK, где авторы довольно известные Josh Bloch и Neal Gafter, используется private static методы). Может вы знаете другие подтверждения той или иной точки зрения?
То есть идеальный ответ, это ответ с цитатами на книги / статьи известных Java авторов или тех кто занимался теорией ООП или проектирования.

Ответ
Руководствуйтесь смыслом, и только им. Строение ваших классов должно отображать не техническую возможность сделать так или иначе (иногда экземплярные методы можно объявить статическими), а отношения между объектами в доменной области. Это и правда база всего ООП (а где ж ещё следовать ООП, если не в Джаве?).
Я не могу привести цитату из умной книги по этому поводу. Но сама идея делать сигнатуру метода зависимой не от его смысла, а от подробностей его конкретной имплементации кажется мне грубым хаком. Даже если это внутренний, приватный метод. Если в публичных методах, предназначенных другим, мы пишем правильно, то почему в методах, предназначенных для себя, писать неправильно?
Для отступления от правильного дизайна нужны веские причины. У ArrayList такие причины есть: он используется в миллионах проектов, и среди них есть критические по времени куски, и там выигрыш пары тактов играет серьёзную роль. Но для большинства классов, которые мы пишем, количество вызовов в наших программах не исчисляются десятками тысяч в секунду, и отступление от правильного дизайна вряд ли оправдано.

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

Пример: оружие рыцаря — меч. Да, у всех рыцарей одинаковое оружие. Тем не менее, метод, выдающий оружие — это очевидно экземплярный метод. Далее, рыцари не пользуются кинжалами. Поэтому геттер кинжала у рыцаря возвращает null. Это тоже экземплярный метод.
class Knight : Warrior { private Weapon createMainWeapon() { return new Sword() } private Dagger getDagger() { return null } }
Далее, количество рыцарей. Соответственно оно не имеет смысла в контексте одного рыцаря, значит, является статическим методом.
class Knight : Warrior { static int numberOfKnights public Knight() { numberOfKnights++ } public static int getNumber() { return numberOfKnights } }
Ну и наконец, метод, который выясняет, в порядке ли амуниция перед битвой, вообще не относится к сфере деятельности рыцаря. Пусть этим займётся оруженосец!
class Squire { Knight master public prepareForBattle() { ... } }