Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一个无状态类有多少字节?_Java_Methods_Singleton - Fatal编程技术网

Java 一个无状态类有多少字节?

Java 一个无状态类有多少字节?,java,methods,singleton,Java,Methods,Singleton,如果我有这些课程: public interface IBinaryCalculator{ double addition(double numb1, double numb2); } public class BinaryCalculator implements IBinaryCalculator{ double addition(double numb1, double numb2){ return numb1+numb2; } } 好的,这个方法应该是静态的,但是我这里有

如果我有这些课程:

public interface IBinaryCalculator{
double addition(double numb1, double numb2);
}

public class BinaryCalculator implements IBinaryCalculator{
 double addition(double numb1, double numb2){
  return numb1+numb2;  

}
}

好的,这个方法应该是静态的,但是我这里有一个接口。singleton是唯一的答案吗?它只是一个BinaryCalc的类?假设我构建了10000个BinaryCalculator,它只有方法,它对性能有影响吗,还是应该使用singleton。

几个问题,几个答案

  • 我不确定一个没有状态的对象占用多少内存,但它需要一些,因为它有一个与之关联的监视器
  • 对于这种类型的类,可以使用静态方法,如java.lang.Math,也可以使用普通的基于实例的方法
  • 单身越来越被认为是不好的风格,应该谨慎使用。在无状态类的情况下,这可能没问题,但就我个人而言,我更喜欢依靠用户不创建无用的对象

  • 在这个特殊的类中,没有什么不能是“静态”的

    当一个类实例的状态数据可能与另一个不同时,您将需要单独的对象

    “单身”是一回事(请原谅双关语;-))

    “静态”是另一回事

    可伸缩性是另一个独立的问题

    底线:如果你需要某个东西成为一个对象,那么就把它变成一个对象。如果一个方法永远都不需要引用实例数据,那就千方百计。如果你愿意的话,把你自己弄出来,让它成为一个静态的方法


    IMHO…

    我不能完全确定,但您似乎过于担心与创建给定对象的许多实例相关的性能问题

    我想你应该先考虑一下设计,然后再考虑一下性能,如果这样的事情成为问题的话。老实说,您的类看起来不像堆中有一百万个对象的类

    您的接口称为SAM类型(单一抽象方法)。JDK本身就有很多这样的例子。例如java.util.Comparator和java.lang.Comparable就是两个很好的例子

    如果您将方法定义为静态的,那么它必须基于您的设计,而不是基于它所执行任务的功能或简单性。你可能比任何人都更了解你的设计,本论坛的开发者可以帮助你提出好的想法,或者挑战你目前的想法,这些想法可能有助于改进你现有的想法

    您提到的singlenton模式旨在防止创建给定类的超过预定义数量的实例,最典型的是它们将其限制为一个实例。在您的设计中,您不清楚为什么要做这样的事情,但对与实例数量相关的性能的担忧听起来并不是最好的理由

    在寻找简化设计的方法时,如果您计划使用不同类型的计算器,您可能希望使用内联匿名内部类,而不是提供接口的类实现,也许您可以使用一个类来放置所有SAM类型实现:

    public class Calculators {
    
        public static BinaryCalculator getBasicCalculator(){
            return new BinaryCalculator() {
    
                @Override
                public double addition(double numb1, double numb2) {
                    return numb1 + numb2;
                }
            };
        }
    
        public static BinaryCalculator getSofisticatedCalculator(){
            return new BinaryCalculator() {
    
                @Override
                public double addition(double numb1, double numb2) {
                    //do any other sofisticated calculation
                    return numb1 + numb2;
                }
            };
        }
    
    }
    
    然后你可以简单地做:

    public static void main(String[] args) {
        BinaryCalculator simple = Calculators.getBasicCalculator();
        BinaryCalculator complex = Calculators.getSofisticatedCalculator();
    
        double result;
        result = simple.addition(10,11);
        result = complex.addition(10,11);
    }
    
    另外,如果允许您进行实验,您可能想尝试一下,在那里您可以将计算器的实现编写为类似这样的lamdba表达式

    BinaryCalculator simple = (num1, num2) -> num1 + num2;
    
    或者甚至在方法中内联,例如

    public class Pair {
            private final double a;
            private final double b;
    
            public Pair(double a, double b){
                this.a = a;
                this.b = b;
            }
    
            public double calculateWith(BinaryCalculator calculator){
                return calculator.addition(a,b);
            }
        }
    
    然后,您可以为SAM类型提供一个简单的lambda实现,如下所示:

    Pair p = new Pair(10,11);
    double result = p.calculateWith( (num1, num2) -> num1 + num2 );
    System.out.println(result);
    
    当然,这只是JDK 8的一个预览版,但是,如果允许您试用最新的功能,那将是一个非常酷的解决方案:-)

    不要做:

    10,000  new BinaryCalculator().addition(42,24);
    
    做:

    如果您使用:

    MemoryMXBean mBean = ManagementFactoryHelper.getMemoryMXBean();
    mBean.getHeapMemoryUsage().getUsed()
    

    在一个单独的测试中,您应该在第一个示例中看到getUsed()的增长和收缩,在第二个示例中看到一个稳定的用法。您还可以使用getUsed()来了解堆的使用速度和GC的使用速度

    类的单个实例使用的内存取决于您使用的JVM,在某些情况下还取决于其他内容。但是一个对象的头通常占用8到16个字节。根据对对象所做的操作,还可能存在其他隐藏状态;e、 g

    • “膨胀”的锁数据结构
    • 对象的标识哈希代码值的存储

    但很可能这对应用程序的性能没有可测量的影响。

    我同意静态方法,但我不能将此方法设置为静态,因为它正在覆盖它。我需要知道这些,因为在存储库模式中,我有相同的情况。每次应用程序需要数据库中的一些实体时,都会构建存储库。请允许我请您提供一些参考来支持大胆的断言,即“单身人士越来越被认为是糟糕的风格”。Singleton是一种模式,就像许多其他模式一样,它有一个有用的上下文,有一系列的优点和缺点,因此,我非常好奇地阅读任何支持这一指控的材料,即它们是一个坏主意,而不强调特定背景下的任何具体缺陷。当然,像这样大胆的指控不可能有一个单一的参考,因为这充其量只是来自轶事。我想在这里告诉你:hhttps://code.google.com/p/testability-explorer/. 他们曾经有一个合适的网站,在那里他们讨论了一些问题,包括静态变量的使用,包括单例模式。不幸的是,这些链接不再起作用了(或者今晚,或者别的什么)。另一部分很难链接,但请注意你在讨论使用单例模式和静态内容时得到的评论。这是一个很长的答案。简单的回答是,单身确实是正当的,这是有背景的。但通常在没有正当理由时使用。我肯定地说,在上述情况下,这是没有道理的。即使它也不会造成任何伤害。一个类的内存占用依赖于JVM。这个问题的目的是
    MemoryMXBean mBean = ManagementFactoryHelper.getMemoryMXBean();
    mBean.getHeapMemoryUsage().getUsed()