静态方法或实例方法中的实际代码

时间:2022-07-02 00:44:07

I'm writing a small library.

我正在写一个小型图书馆。

public class MyClass {

    public static String doSomethingWithString(final String s) {
        new MyClass().doSomething(s);
    }

    public String doSomething(final String s) {
        return null;
    }
}

Or I can do like this.

或者我可以这样做。

public class MyClass {

    public static String doSomethingWithString(final String s) {
        return null;
    }

    public String doSomething(final String s) {
        return doSomethingWithString(s);
    }
}

Which style is preferable? Are they same?

哪种风格更好?它们一样吗?

UPDATE

UPDATE

Thank you for comments and answers.

感谢您的评论和解答。

Here are two classes.

这是两个班级。

public class IdEncoder {

    private static String block(final long decoded) {
        final StringBuilder builder = new StringBuilder(Long.toString(decoded));
        builder.append(Integer.toString(
            ThreadLocalRandom.current().nextInt(9) + 1)); // 1-9
        builder.append(Integer.toString(
            ThreadLocalRandom.current().nextInt(9) + 1)); // 1-9
        builder.reverse();
        return Long.toString(
            Long.parseLong(builder.toString()), Character.MAX_RADIX);
    }

    public static String encodeLong(final long decoded) {
        return block(decoded >>> 0x20) + "-" + block(decoded & 0xFFFFFFFFL);
    }

    public String encode(final long decoded) {
        return encodeLong(decoded);
    }
}

And another style.

而另一种风格。

public class IdDecoder {

    public static long decodeLong(final String encoded) {
        return new IdDecoder().decode(encoded);
    }

    public long decode(final String encoded) {
        final int index = encoded.indexOf('-');
        if (index == -1) {
            throw new IllegalArgumentException("wrong encoded: " + encoded);
        }
        return (block(encoded.substring(0, index)) << 32)
               | (block(encoded.substring(index + 1)));
    }

    private long block(final String encoded) {
        final StringBuilder builder = new StringBuilder(
            Long.toString(Long.parseLong(encoded, Character.MAX_RADIX)));
        builder.reverse();
        builder.deleteCharAt(builder.length() - 1);
        builder.deleteCharAt(builder.length() - 1);
        return Long.parseLong(builder.toString());
    }
}

2 个解决方案

#1


3  

If you are just picking between these 2 options, take the second one.

如果您只是在这两个选项之间进行选择,请选择第二个选项。

The reason is the first requires you to allocate a new dummy object on the heap just to call a method. If there is truly no other difference, don't waste the time and space and just call the static method from the class.

原因是第一个要求你在堆上分配一个新的虚拟对象只是为了调用一个方法。如果真的没有其他区别,不要浪费时间和空间,只需从类中调用静态方法。

The second is more akin to a static Utility function, which are a fine coding practice.

第二种更类似于静态效用函数,它是一种精细的编码实践。

#2


2  

When writing a library, ease of use dramatically trumps general best practices. Your method should be static if it doesn't make sense for a user to instantiate something in order to access it. However often it is actually much cleaner and more powerful for a method to be part of an object, because it allows the user (as well as the library writer) to override it in child classes.

在编写库时,易用性大大胜过一般的最佳实践。如果用户无法实例化某些内容以便访问它,那么您的方法应该是静态的。然而,对于作为对象一部分的方法,它实际上通常更清晰,更强大,因为它允许用户(以及库编写者)在子类中覆盖它。

In a sense, you aren't actually asking a programming question, but a UX question. Ask yourself how your users would best benefit from accessing your code, and implement it that way. As a good benchmark, look at the Guava API; it consists of many static utility classes, but just as many classes and interfaces designed to be easily extended. Do what you think is best.

从某种意义上说,你实际上并没有问一个编程问题,而是一个UX问题。问问自己,您的用户如何最好地访问您的代码,并以这种方式实现它。作为一个很好的基准,看看Guava API;它由许多静态实用程序类组成,但同样多的类和接口也可以轻松扩展。做你认为最好的事情。

#1


3  

If you are just picking between these 2 options, take the second one.

如果您只是在这两个选项之间进行选择,请选择第二个选项。

The reason is the first requires you to allocate a new dummy object on the heap just to call a method. If there is truly no other difference, don't waste the time and space and just call the static method from the class.

原因是第一个要求你在堆上分配一个新的虚拟对象只是为了调用一个方法。如果真的没有其他区别,不要浪费时间和空间,只需从类中调用静态方法。

The second is more akin to a static Utility function, which are a fine coding practice.

第二种更类似于静态效用函数,它是一种精细的编码实践。

#2


2  

When writing a library, ease of use dramatically trumps general best practices. Your method should be static if it doesn't make sense for a user to instantiate something in order to access it. However often it is actually much cleaner and more powerful for a method to be part of an object, because it allows the user (as well as the library writer) to override it in child classes.

在编写库时,易用性大大胜过一般的最佳实践。如果用户无法实例化某些内容以便访问它,那么您的方法应该是静态的。然而,对于作为对象一部分的方法,它实际上通常更清晰,更强大,因为它允许用户(以及库编写者)在子类中覆盖它。

In a sense, you aren't actually asking a programming question, but a UX question. Ask yourself how your users would best benefit from accessing your code, and implement it that way. As a good benchmark, look at the Guava API; it consists of many static utility classes, but just as many classes and interfaces designed to be easily extended. Do what you think is best.

从某种意义上说,你实际上并没有问一个编程问题,而是一个UX问题。问问自己,您的用户如何最好地访问您的代码,并以这种方式实现它。作为一个很好的基准,看看Guava API;它由许多静态实用程序类组成,但同样多的类和接口也可以轻松扩展。做你认为最好的事情。