【问题标题】:Best way for accessing methods of java class is creating objects or make a method Static type?访问 java 类方法的最佳方法是创建对象或创建方法静态类型?
【发布时间】:2015-06-26 17:46:50
【问题描述】:

访问 java 类的方法的最佳方式是什么?

  1. 创建对象 - 如果我们每次都创建对象,那么它会消耗大量内存。
  2. 如果创建对象的成本很高,那么为什么我们不总是使用静态方法来访问 java 类的资源呢?

提前致谢!!

【问题讨论】:

标签: java object static-methods


【解决方案1】:

这完全取决于方法的行为是应该针对类的一个实例,还是针对每个可能的实例。

我们并不总是使用静态,因为有时我们希望对象做出不同的反应。 假设我们有一个 Person 类,有两个“实例”,你和我。 如果我们要实现一个方法:

public static String getName(){ ....
}

我们中的一个人将不得不改变他的名字。为此,您希望每个 Person 实例都有不同的回复,因此这里不适合使用静态。

在这里,您需要两个实例,一个实例变量名称(由构造函数或 mutator 设置)对我来说会返回“Hans”,对你来说会返回“Pushpendra”

【讨论】:

    【解决方案2】:

    一个静态方法属于该类 并且非静态方法属于 一个类的对象。这是一个 只能调用非静态方法 在一个类的对象上 属于。静态方法可以 但是在课堂上都被称为 以及类的对象。一种 静态方法只能访问静态 成员。非静态方法可以 访问静态和非静态 成员因为当时 调用静态方法,类 可能不会被实例化(如果是 调用类本身)。在里面 其他情况下,非静态方法可以 仅在类有时调用 已经实例化了。一个静态的 方法由所有实例共享 班级。

    我有来自here的数据。

    【讨论】:

      【解决方案3】:

      最好的方法!!?
      没有任何最好的方法。根据您的目的,所有方法都是有用的和好的。

      方法static 的决定不仅仅取决于对象的创建和它的开销,你还需要考虑可用性。

      如果一个方法可以为所有实例共享并且不需要依赖于任何对象属性,那么您可以很高兴地将其设为静态。

      它还需要考虑你将如何使用它。记住静态方法或字段不属于对象,它属于类

      【讨论】:

        【解决方案4】:

        对于使用静态的类的所有实例,您希望行为应该保持不变,这是一种节省内存的好习惯。

        如果您希望每个类实例更改方法行为,请使用非静态方法。

        假设您有一个构建客户订单的程序。

        返回任何订单的标准包装成本的方法应该是静态的。不依赖于类属性的方法应该是静态的。

        而根据所选菜单返回订单成本的方法应该是非静态的。

        还有太多的静态方法会增加类加载时间。 静态方法不能被覆盖,所以你不能利用多态的力量。通常静态方法用作实用程序类,如Math.double() Math.float()

        【讨论】:

          【解决方案5】:

          对象确实更昂贵,但出于维护原因,它通常是值得的: 您的类封装了传递给静态方法会很乏味的数据。例如。如果“登录”方法需要从 MySQL 数据库和 Mongo 中查找用户数据 - 那么将数据库连接传递给每个调用是很乏味的:

             public class LoginService{
                    public static login(String user,String password, DataSource mySQLConnections, MongoClient mongoClient) ... 
          

          这个签名很难阅读,更糟糕的是:它对多态不灵活。如果我们曾经将用户数据从 mySQL+mongo 迁移到 LDAP,那么我们需要修复对“login(user,password,LDAPClient)”的每个调用

          现在,您可能仍然认为这可以静态解决:

             public class LoginService{
                    private static DataSource mySQLConnections;
                    private static MongoClient mongoClient;
                    public static login(String user,String password) ... 
          
             // and if we ever migrate to LDAP, we just change the internal statics, without affecting the public signature:
             public class LoginService{
                    private static LDDAPClient;
                    public static login(String user,String password) ... 
          

          有时这已经足够了,但许多程序员仍然觉得它有局限性。有关详细信息,请阅读 Spring 和“依赖注入”,但底线是 - 我可能想使用 LoginService,有几个实例(一个使用 LDAP,另一个使用 MySQL+Mongo),并根据一些管理切换它们命令,甚至只是为了测试。这归结为具有不同实现类的接口,每个类都封装了其所需的帮助器:

                 public interface LoginService{
                        public login(String user,String password) ... 
                 }
                 public class LoginServiceDb implements LoginService{
                        private DataSource mySqlConnections;
                        private MongoClient mongoClient;
                        public login(String user,String password) 
                              // use the databases
                        ...
                 }
                 public class LoginServiceLDAP implements LoginService{
                        private LDAPClient ldap;
                        public login(String user,String password) 
                          // use LDAP
                        ...  
          }
          

          另请注意: 对垃圾收集的影响可能不会那么糟糕(取决于您的需求以及您的“实时”程度)。一些对象可能会被缓存和重用。一些对象的使用非常短暂,以至于它们仍然处于 GC 处理得相当好的“婴儿”一代

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-22
            • 2023-03-26
            • 2018-04-20
            • 2015-04-28
            • 2010-10-17
            相关资源
            最近更新 更多