静态工厂方法问题!

发布于 2024-10-30 14:29:43 字数 537 浏览 3 评论 0原文

在这个网站中,它说每次都不会创建一个新对象,这会提高效率,但据我所见,每次都会在静态方法中创建一个对象。

不需要创建新对象 每次调用时 - 对象可以是 如有必要,可缓存并重用。

http://www.javapractices.com/topic/TopicAction.do?Id=21

那么为什么静态工厂方法如此高效呢?

不是写这样的东西: Object obj=new Object 与我所做的相同 Object obj=Someclass.GetObj();

class Someclass
{
   public static Object GetObj()
   {
     return new Object
   }
}

有缓存,但无论如何都会创建一个新对象......

in this site it says that a new object isnt being created each time , which leads to efficiency, but by what i can see an object is being created each time in the static method..

do not need to create a new object
upon each invocation - objects can be
cached and reused, if necessary.

http://www.javapractices.com/topic/TopicAction.do?Id=21

so why are the static factory methods are so efficient?

isnt writing something like this : Object obj=new Object is same as if i did Object obj=Someclass.GetObj();

class Someclass
{
   public static Object GetObj()
   {
     return new Object
   }
}

There is caching, but a new object is created either way...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

随风而去 2024-11-06 14:29:43

对象可以被缓存和重用。他们并不总是这样。还有许多其他优点,例如:

  • 的方法进行更好的命名。Effective
  • 对返回子类

Java 中对此有一个条目,所以请继续阅读它。无论如何,这本书是必读的。

更新:正如我所说,对象可以被缓存。但这取决于实施。您显示的不会缓存它们。 Peter 展示的那个缓存了它们。你有这个选择。对于构造函数 - 你不需要。

Objects can be cached and reused. They aren't always. There are a number of other advantages, like:

  • better naming of the method
  • returning subclasses

There is an item in Effective Java for that, so go ahead and read it. The book is a must-read anyway.

Update: as I said, object can be cached. But it depends on the implementation. The one you show does not cache them. The one shown by Peter caches them. You have that option. With a constructor - you don't.

子栖 2024-11-06 14:29:43

它们更灵活 - 例如,如果新对象的输入参数无效,您可以返回 null 或某些 null 对象实现(=instance,它不执行任何操作,但不会通过 NullPointerException 破坏您的代码),或者如前所述通过其他人,您可以缓存创建的实例。与构造函数相比,使用工厂方法还有另一个好处 - 您可以将它们命名为任何您喜欢的名称,如果有多个带有大量可选参数的构造函数,这会更具可读性。

编辑:如果您只想使用一个实例,您可以使用这个简单的工厂:

class Someclass{
  private static Object o=new Object();

  public static Object getObj(){
    return o;
  }
}

They are more flexible - for example if the input parameters for new object are not valid, you can return null or some null object implementation (=instance, which does nothing, but will not break your code by NullPointerException), or, as previously mentioned by others, you can cache created instances. There is another benefit from using factory methods over constructors - you can name them whatever you like, which can be more readable, if there are multiple constructors with lots of optional parameters.

EDIT: if you want to use only one instance, you can use this simple factory:

class Someclass{
  private static Object o=new Object();

  public static Object getObj(){
    return o;
  }
}
温柔戏命师 2024-11-06 14:29:43

当您使用new Object()时,必须创建一个新对象。

如果您使用静态工厂,它可以选择创建一个新对象,也可以重用现有对象。

一个简单的示例是使用 Integer.valueOf(int) 而不是 new Integer(int)。静态工厂具有小整数的缓存,并且可以保存大部分整数的创建。对于某些用例,这可以是使用的所有整数。后一种情况总是会创建一个新对象,效率相对较低。

When you use new Object(), a new Object has to be created.

If you use a static factory, it can optionally create a new object, or it can reuse an existing one.

A simple example is using Integer.valueOf(int) instead of new Integer(int). The static factory has a cache of small integers and can save to the creation of a significant portion of integers. For some use cases this can be all the integers used. The later case will always create a new object which is relatively inefficient.

云归处 2024-11-06 14:29:43

您提供的链接提供了对工厂模式的非常不同的解释。通常,工厂模式用于获取实现相同接口但为同一合约提供不同行为的类的实例。它允许我们在运行时选择不同的实现。查看此处的示例:

http://www.allapplabs.com/java_design_patterns/factory_pattern.htm

工厂模式一般不用于缓存对象。单例模式的定义是为了确保只创建对象的一个​​实例。

The link you presented provides very different explanation of a Factory Pattern. Generally factory pattern is used to obtain instances of classes whcih implement same interface but provide different behavior for the same contract. It allows us to choose different implementation at run time. Check out the example here:

http://www.allapplabs.com/java_design_patterns/factory_pattern.htm

Factory pattern is not generally used for caching objects. Singleton pattern is defined to ensure only one instance of the object is created.

洒一地阳光 2024-11-06 14:29:43

这个想法是你将它们用作策略。如果稍后您想实现缓存,只需更改该方法并将其添加到其中即可。将此与将“new Bla()”分散在整个代码中并尝试为 Bla 类实现缓存进行比较。

由于该方法是静态的,并且通常只有几行代码,这意味着它可以在编译时解析,甚至内联。

因此,使用“new Bla()”代替工厂方法根本没有任何优势。

The idea is that you use them as a strategy. If later you want to implement caching, you just change that method and add it in there. Compare this with having "new Bla()" scattered all over the code, and trying to implement caching for the Bla class.

Since the method is static, and usually just a few lines of code, it means it can be resolved at compile time, and even inlined.

Thus there is no advantage of using "new Bla()" instead of factory methods at all.

甚是思念 2024-11-06 14:29:43

在某些情况下使用工厂可以使代码更灵活、更快并且可读性更好。

例如,想象一下,您必须编写从 url 下载一些数据的类

public class WavAudio {
      private byte[] raw;
      private static HashMap<String,WavAudio> cache;
      private WavAudio(byte[] raw){
          this.raw=raw;
      }
      public static loadFromUrl(String someUrl){
          //If data has been loaded previously we don't have to do this more (faster..)
          if (cache.containsKey(someUrl))
               return cache.get(someUrl);
          //Else we'll load data (that would take some time)
          InputStream ires=(new URL(someUrl)).openStream();    
          ByteArrayOutputStream baos=new ByteArrayOutputStream();
          byte[] raw = new byte[4096];          
          int nBytesRead;
          while ((nBytesRead = ires.read(raw, 0, raw.length))>0)
          baos.write(raw, 0, raw); 
          byte[] downloaded=baos.toByteArray();
          WavAudio curr=new WavAudio(raw);
          cache.put(someUrl,raw);
          return raw;
      }      

      public static void main(String[] args){
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
          SomePlayer.play(wav); //the first melody is playing
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_2");
          SomePlayer.play(wav); //the second melody is playing
          //won't be downloaded twice
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
          SomePlayer.play(wav);
      }
}

Using factory in some situations you could make your code more flexible, faster and also better readable.

For example, imagine, you have to write class which download some data from url

public class WavAudio {
      private byte[] raw;
      private static HashMap<String,WavAudio> cache;
      private WavAudio(byte[] raw){
          this.raw=raw;
      }
      public static loadFromUrl(String someUrl){
          //If data has been loaded previously we don't have to do this more (faster..)
          if (cache.containsKey(someUrl))
               return cache.get(someUrl);
          //Else we'll load data (that would take some time)
          InputStream ires=(new URL(someUrl)).openStream();    
          ByteArrayOutputStream baos=new ByteArrayOutputStream();
          byte[] raw = new byte[4096];          
          int nBytesRead;
          while ((nBytesRead = ires.read(raw, 0, raw.length))>0)
          baos.write(raw, 0, raw); 
          byte[] downloaded=baos.toByteArray();
          WavAudio curr=new WavAudio(raw);
          cache.put(someUrl,raw);
          return raw;
      }      

      public static void main(String[] args){
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
          SomePlayer.play(wav); //the first melody is playing
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_2");
          SomePlayer.play(wav); //the second melody is playing
          //won't be downloaded twice
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
          SomePlayer.play(wav);
      }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文