java Java构造函数和静态方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13803032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:02:10  来源:igfitidea点击:

Java Constructor and static method

java

提问by ram

When should I use a constructor and when should I use static method?

什么时候应该使用构造函数,什么时候应该使用静态方法?

Can you explain above with small snippet? I skimmed through a few threads but I'm still not clear with this.

你能用小片段解释上面吗?我浏览了一些线程,但我仍然不清楚这一点。

回答by Ioan

Joshua Blochadvises to favor static factory methods instead of constructors (which I think is a good practice).Couple of advantages and disadvantages :

Joshua Bloch建议使用静态工厂方法而不是构造函数(我认为这是一个很好的做法)。几个优点和缺点:

Advantagesof static factory methods :

静态工厂方法的优点

  • unlike constructors, they have names
  • unlike constructors, they are not required to create a new object each time they're invoked (you can cache instances : e.g. Boolean.valueOf(..)
  • unlike constructors, they can return an object of any subtype of their return type (great flexibility)
  • 与构造函数不同,它们有名称
  • 与构造函数不同,它们不需要在每次调用时都创建一个新对象(您可以缓存实例:例如 Boolean.valueOf(..)
  • 与构造函数不同,它们可以返回其返回类型的任何子类型的对象(非常灵活)

Disadvantagesof static factory methods :

静态工厂方法的缺点

  • They are not really distiguishable from other static methods (it's hard to find out how to initialize an object if you are not familiar with the API)
  • The main disadvantage (if you use only static factory methods, and make constructors private) is that you cannot subclass that class.
  • 它们与其他静态方法并没有真正的区别(如果您不熟悉 API,则很难找出如何初始化对象)
  • 主要缺点(如果您只使用静态工厂方法,并将构造函数设为私有)是您不能子类化该类。

回答by Peter Lawrey

Use a public constructor when you only ever want to return a new object that type and you want simplicity.

当您只想返回该类型的新对象并且想要简单时,请使用公共构造函数。

A good example is StringBuilder as it's mutable and you are likely to want a new object each time.

一个很好的例子是 StringBuilder,因为它是可变的,你可能每次都想要一个新对象。

public String toString() {
    StringBuilder sb = new StringBuilder();
    // append fields to the sb
    return sb.toString();
}

Use a static factor method when you might want to re-use objects (esp if immutable), you might want to return a sub-class or you want descriptice construction. A good example is EnumSet which has a number of static factories which do different things even though some have the same arguments.

当您可能想要重用对象(尤其是不可变的)、您可能想要返回一个子类或您想要描述构造时,请使用静态因子方法。一个很好的例子是 EnumSet,它有许多静态工厂,即使有些工厂有相同的参数,它们也会做不同的事情。

EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);

In this case, using a static factory makes it clear what the difference between these two ways of construction the set.

在这种情况下,使用静态工厂可以清楚地表明这两种构造集合的方式之间的区别。

Also EnumSet can return two different implementations, one optimised for enums with a small number of values (<= 64) RegularEnumSetand another for many values called JumboEnumSet

EnumSet 还可以返回两种不同的实现,一种针对具有少量值(<= 64)的枚举进行优化RegularEnumSet,另一种针对称为JumboEnumSet

回答by stacker

Always use a constructor if your class has a state (even for a single instance; singleton pattern ).

如果您的类具有状态(即使对于单个实例;单例模式),请始终使用构造函数。

Only use static for utility methods like in java.lang.Math

仅对 java.lang.Math 等实用方法使用静态

Example:

例子:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

Doesn't change any state (instance variables) of an object, thus it can be declared static.

不改变对象的任何状态(实例变量),因此它可以被声明为静态。

回答by Android Killer

  1. Use constructor when you need an object and other stuffs like functions and variables having one copy for every object.
  2. when you want to do something without creating object then use static method.

    Example:
    public class Test {
    public int value;
    public static int staticValue;
    public int getValue() {
    return ++value;
    }
    
    public static int getStaticValue() {
    return ++staticValue;
    }
    }
    
    public class TestClass {
    public static void main(String[] args) {
    Test obj = new Test();
    Test obj1 = new Test();
    S.o.p(obj.getValue());
    S.o.p(obj1.getValue));
    S.o.p(Test.getStaticValue());
    S.o.p(Test.getStaticValue());
    }
    }
    
  1. 当你需要一个对象和其他东西时使用构造函数,比如每个对象都有一个副本的函数和变量。
  2. 当您想在不创建对象的情况下做某事时,请使用静态方法。

    Example:
    public class Test {
    public int value;
    public static int staticValue;
    public int getValue() {
    return ++value;
    }
    
    public static int getStaticValue() {
    return ++staticValue;
    }
    }
    
    public class TestClass {
    public static void main(String[] args) {
    Test obj = new Test();
    Test obj1 = new Test();
    S.o.p(obj.getValue());
    S.o.p(obj1.getValue));
    S.o.p(Test.getStaticValue());
    S.o.p(Test.getStaticValue());
    }
    }
    

回答by Joe Kearney

Static factory methods have names, constructors don't. Thus factory methods can carry natural documentation about what they do that constructors can't. For example, see the factory methods in the Guava Libraries, like ImmutableMap.copyOf(otherMap). While this might have little effect on behaviour of construction, it has a huge effect on readability of the code. Definitely consider this if you're publishing an API.

静态工厂方法有名字,构造函数没有。因此,工厂方法可以携带关于它们做什么而构造函数不能做的自然文档。例如,请参阅 Guava 库中的工厂方法,如ImmutableMap.copyOf(otherMap). 虽然这可能对构造行为几乎没有影响,但它对代码的可读性有巨大影响。如果您要发布 API,请务必考虑这一点。

Also you can use a factory when you need to do any more complicated configuration of the object you're creating, especially if you need to publish to other threads (registering in pools, exposing as an MBean, all manner of other things...) to avoid racy publication. (See e.g. Java Concurrency In Practice section 3.2)

当您需要对正在创建的对象进行任何更复杂的配置时,您也可以使用工厂,特别是如果您需要发布到其他线程(在池中注册,作为 MBean 公开,以及所有其他事情...... ) 以避免不正当发布。(参见例如 Java 并发实践部分 3.2)

Static methods that dosomething (e.g. Math.min) are not really the same thing as static factories, which can be considered direct replacements for constructors, with added flexibility, evolvability and (often) clarity.

执行某事(例如Math.min)的静态方法与静态工厂实际上并不是一回事,静态工厂可以被认为是构造函数的直接替代品,具有更高的灵活性、可进化性和(通常)清晰性。

回答by ipinak

Whenever you need to create an instance of an object you will have to use the constructor.

每当您需要创建对象的实例时,您都必须使用构造函数。

So, if you want to create a Car object, then you will need a constructor for that.

所以,如果你想创建一个 Car 对象,那么你将需要一个构造函数。

The keyword static means, that your method can be called without creating an instance.

关键字 static 意味着可以在不创建实例的情况下调用您的方法。

回答by ipinak

class Car
{
   private int num_of_seats;

   public Car(int number_of_seats)
   {
      this.num_of_seats = number_of_seats;
   }

   // You want to get the name of the class that has to do with
   // this class, but it's not bounded with any data of the class
   // itself. So you don't need any instance of the class, and 
   // you can declare it as static.
   static String getClassName()
   {
      return "[Car]";
   }
}

In general you will use static class with data that are not correlated with the instance of the object.

通常,您将对与对象实例无关的数据使用静态类。

Another example is:

另一个例子是:

class Ring
{
   private List nodes;

   public Ring(List nodes) 
   {
      this.nodes = nodes;
   }

   // You want to calculate the distance of two ids on the ring, but
   // you don't care about the ring. You care only about the ids.
   // However, this functionality logical falls into the notion of
   // the ring, that's why you put it here and you can declare it
   // as static. That way you don't have to manage the instance of 
   // ring.
   static double calculateDistance(int id_1, int id_2)
   {
      return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
   }
}

As the posts above say, it's just a matter of what you want to do and how you want to do it. Also, don't try to understand everything rightaway, write some code then try different approaches of that code and try to understand what your code does. Examples are good, but you need to write and then understand what you did. I think it's the only way you will figure out why you do staff the way you have to do.

正如上面的帖子所说,这只是您想做什么以及如何做的问题。另外,不要试图立即理解所有内容,编写一些代码然后尝试该代码的不同方法并尝试理解您的代码的作用。例子很好,但你需要写下来然后理解你做了什么。我认为这是唯一的方法,你会弄清楚你为什么要按照你必须做的方式来安排员工。

回答by ipinak

i.e. if you want to use a singleton, which means that you have only one instance of the object, which might be shared with others, then you need a static method, which will internally will call the constructor. So, every time someone wants an instance of that object you will return always the same, thus you will consume memory only for one. You always need a constructor in object oriented programming, in every OO language. In java an in many other languages the default constructor of an object is implied, and built automatically. But you need some custom functionality you have to make your own.

即如果你想使用单例,这意味着你只有一个对象实例,它可能与其他人共享,那么你需要一个静态方法,它将在内部调用构造函数。因此,每次有人想要该对象的实例时,您将始终返回相同的内容,因此您只会消耗一个内存。在面向对象的编程中,在每种 OO 语言中,您总是需要一个构造函数。在 Java 和许多其他语言中,对象的默认构造函数是隐含的,并且是自动构建的。但是您需要一些自定义功能,您必须自己制作。

Above you see a few good examples of the usage. However, if you have something specific in your mind, please let us know. I mean if you have a specific case where you are not sure if you should use a static method or a constructor. Anyhow, you will definitely need a constructor, but I am not sure about the static method.

在上面您可以看到一些很好的用法示例。但是,如果您有什么具体想法,请告诉我们。我的意思是,如果您有一个特定的情况,您不确定是否应该使用静态方法或构造函数。无论如何,您肯定需要一个构造函数,但我不确定静态方法。

回答by Parvin Gasimzade

Static methods do not have to instantiate new objects everytime. Since object instantiation is expensive it allows instances to be cached within the object. So, it can improve performance.

静态方法不必每次都实例化新对象。由于对象实例化是昂贵的,它允许将实例缓存在对象中。因此,它可以提高性能。

This is the explanation from the Effective Java:

这是Effective Java的解释:

This allows immutable classes (Item 15) to use preconstructed instances, or to cache instances as they're constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects. The Boolean.valueOf(boolean) method illustrates this technique: it never creates an object. This technique is similar to the Flyweight pattern [Gamma95, p. 195]. It can greatly improve performance if equivalent objects are requested often, especially if they are expensive to create.

这允许不可变类(条款 15)使用预先构造的实例,或在构造实例时缓存实例,并重复分配它们以避免创建不必要的重复对象。Boolean.valueOf(boolean) 方法说明了这种技术:它从不创建对象。这种技术类似于享元模式 [Gamma95, p. 195]。如果经常请求等效对象,它可以大大提高性能,特别是如果创建它们的成本很高。