首页 文章

Java:何时使用静态方法

提问于
浏览
752

我想知道何时使用静态方法?假如我有一个带有一些getter和setter的类,一个或两个方法,我希望这些方法只能在类的实例对象上调用 . 这是否意味着我应该使用静态方法?

例如

Obj x = new Obj();
x.someMethod

要么

Obj.someMethod

(这是静态方式吗?)

我很困惑!

20 回答

  • 3

    在阅读Misko的文章之后,我认为从测试的角度来看static methods是不好的 . 您应该使用factories(可能使用依赖注入工具,如Guice) .

    如何确保我只有一件东西

    只有一个东西“如何确保我只有一个东西”的问题很好地回避 . 您只在main中实例化一个ApplicationFactory,因此,您只实例化所有单例的单个实例 .

    静态方法的基本问题是它们是程序代码

    静态方法的基本问题是它们是程序代码 . 我不知道如何对程序代码进行单元测试 . 单元测试假定我可以单独实例化我的应用程序 . 在实例化期间,我使用mocks / friendlies连接依赖项,这取代了真正的依赖项 . 通过程序编程,没有什么可以“连线”,因为没有对象,代码和数据是分开的 .

  • 39

    仅在以下方案中定义静态方法:

    • 如果您正在编写实用程序类,则不应更改它们 .

    • 如果方法未使用任何实例变量 .

    • 如果任何操作不依赖于实例创建 .

    • 如果有一些代码可以被所有实例方法轻松共享,请将该代码提取到静态方法中 .

    • 如果您确定永远不会更改或覆盖方法的定义 . 由于静态方法无法被覆盖 .

  • 477

    static 方法是一种方法,它不需要初始化任何对象来调用它 . 您是否注意到 static 用于Java中的 main 函数?程序执行从那里开始,没有创建对象 .

    请考虑以下示例:

    class Languages 
     {
         public static void main(String[] args) 
         {
             display();
         }
    
         static void display() 
         {
             System.out.println("Java is my favorite programming language.");
         }
      }
    
  • 146

    在eclipse中,您可以启用警告,以帮助您检测潜在的静态方法 . (在突出显示的行上方是另一个我忘了突出显示的行)

    eclipse setting

  • 6

    一个经验法则:问问自己“即使没有构建Obj,这个方法也有意义吗?”如果是这样,那肯定是静态的 .

    所以在类 Car 中你可能有一个静态的方法 double convertMpgToKpl(double mpg) ,因为有人可能想知道35mpg转换成什么,即使没有人建造过汽车 . 但是 void setMileage(double mpg) (设定一个特定汽车的效率)在任何汽车构建之前调用该方法是不可能的 .

    (顺便说一下,反过来并不总是这样:你有时会有一个涉及两个 Car 对象的方法,但仍然希望它是静态的 . 例如 Car theMoreEfficientOf( Car c1, Car c2 ) . 虽然这可以转换为非静态版本,但有些人会争辩说因为没有't a 273323 choice of which Car is more important, you shouldn'强制调用者选择一个Car作为你将调用方法的对象 . 但是这种情况只占所有静态方法的一小部分 . )

  • 6

    如果对任何方法应用static关键字,则称为静态方法 .

    • 静态方法属于类而不是类的对象 .

    • 调用静态方法而无需创建类的实例 .

    • 静态方法可以访问静态数据成员并可以更改它的值 .

    //更改所有对象的公共属性的程序(静态字段) .

    class Student9{  
     int rollno;  
     String name;  
     static String college = "ITS";  
    
     static void change(){  
     college = "BBDIT";  
     }  
    
     Student9(int r, String n){  
     rollno = r;  
     name = n;  
     }  
    
     void display (){System.out.println(rollno+" "+name+" "+college);}  
    
    public static void main(String args[]){  
    Student9.change();  
    
    Student9 s1 = new Student9 (111,"Indian");  
    Student9 s2 = new Student9 (222,"American");  
    Student9 s3 = new Student9 (333,"China");  
    
    s1.display();  
    s2.display();  
    s3.display();  
    }  }
    

    O / P:111印度BBDIT 222美国BBDIT 333中国BBDIT

  • 3

    如果希望能够在没有类实例的情况下访问该方法,请使用静态方法 .

  • 16

    实际上,我们在类中使用静态属性和方法,当我们想要使用我们程序的某些部分应该存在时,直到我们的程序运行 . 我们知道,要操纵静态属性,我们需要静态方法,因为它们不是实例变量的一部分 . 如果没有静态方法,操纵静态属性非常耗时 .

  • 3

    静态方法是Java中可以在不创建类对象的情况下调用的方法 . 它属于这个类 .

    当我们不需要使用实例调用方法时,我们使用静态方法 .

  • 4

    静态方法有两个主要目的:

    • 对于不需要任何对象状态的实用程序或辅助方法 . 由于不需要访问实例变量,因此使用静态方法不需要调用者只是为了调用方法来实例化对象 .

    • 对于所有类的实例共享的状态,如计数器 . 所有实例必须共享相同的状态 . 仅使用该状态的方法也应该是静态的 .

  • 1244

    使用静态有一些正当理由方法:

    • Performance :如果你想要运行一些代码,并且曾经读过James Gosling声明你没有找到源代码 - 因此它可能完全是假的 . 是的,它是微优化,可能不需要 . 而且我们程序员从不做不需要的东西只是因为它们很酷,对吧?

    • Practicality :而不是调用 new Util().method(arg) ,使用静态导入调用 Util.method(arg)method(arg) . 更简单,更短 .

    • Adding methods :你真的希望类String有一个 removeSpecialChars() 实例方法,但它's not there (and it shouldn' t,因为你的项目's special characters may be different from the other project' s),你不能添加它(因为Java有点理智),所以你创建了一个实用程序类,并调用 removeSpecialChars(s) 而不是 s.removeSpecialChars() . 甜 .

    • Purity :采取一些预防措施,你的静态方法将是pure function,也就是说,它唯一依赖的是它的参数 . 数据输入,数据输出 . 这更容易阅读和调试,因为您没有担心继承怪癖 . 您也可以使用实例方法来完成它,但编译器将使用静态方法帮助您(通过不允许引用实例属性,重写方法等) .

    如果你想制作单身,你还必须创建一个静态方法,但是......不要 . 我的意思是,三思而后行 .

    现在,更重要的是,为什么你不想创建静态方法?基本上, polymorphism goes out of the window . 您将无法覆盖该方法,也无法在接口中声明它(Java 8之前的版本) . 它从您的设计中获得了很大的灵活性 . 此外,如果您需要 state ,如果您不小心,最终会出现大量的 concurrency bugs 和/或瓶颈 .

  • 9

    静态方法和变量是Java中'Global'函数和变量的受控版本 . 可以使用 classname.methodName()classInstanceName.methodName() 访问哪些方法,即可以使用类名以及类的实例访问静态方法和变量 .

    类不能声明为static(因为它没有意义 . 如果一个类被声明为public,它可以从任何地方访问),内部类可以声明为static .

  • 11

    静态: Obj.someMethod

    如果要提供对方法的类级别访问权限,请使用 static ,即方法应该在没有类实例的情况下可调用 .

  • 4

    不需要在对象上调用静态方法,也就是在使用它时 . 示例:您的Main()是静态的,您不会创建一个对象来调用它 .

  • 30

    不,静态方法与实例无关;他们属于这个 class . 静态方法是你的第二个例子;实例方法是第一个 .

  • 1

    静态方法与实例无关,因此它们无法访问类中的任何非静态字段 .

    如果方法不使用类的任何字段(或仅静态字段),则可以使用静态方法 .

    如果使用类的任何非静态字段,则必须使用非静态方法 .

  • 2

    应该在类上调用静态方法,应该在类的实例上调用Instance方法 . 但这在现实中意味着什么呢?这是一个有用的例子:

    汽车类可能有一个名为Accelerate()的实例方法 . 如果汽车实际存在(已经构建),您只能加速汽车,因此这将是一个实例方法 .

    汽车类也可能有一个名为GetCarCount()的计数方法 . 这将返回创建(或构建)的汽车总数 . 如果没有构建汽车,这个方法将返回0,但它仍然可以被调用,因此它必须是静态方法 .

  • 3

    如果可以使用静态方法

    • 一个人不想对实例执行操作(实用程序方法)

    正如本文上面的几个答案中所提到的,将里程转换为公里,或计算从华氏温度到摄氏温度的温度,反之亦然 . 使用静态方法的这些示例,它不需要在堆内存中实例化整个新对象 . 考虑下面

    1. new ABCClass(double farenheit).convertFarenheitToCelcium() 
    2. ABCClass.convertFarenheitToCelcium(double farenheit)
    

    前者为每个方法调用创建一个新的类足迹,Performance,Practical . 示例是下面的Math和Apache-Commons库StringUtils类:

    Math.random()
    Math.sqrt(double)
    Math.min(int, int)
    StringUtils.isEmpty(String)
    StringUtils.isBlank(String)
    
    • 一个人想要用作一个简单的功能 . 显式传递输入,并将结果数据作为返回值 . 继承,对象实例不会出现 . Concise, Readable .

    NOTE :很少有人反对静态方法的可测试性,但也可以测试静态方法!使用jMockit,可以模拟静态方法 . Testability . 示例如下:

    new MockUp<ClassName>() {
        @Mock
        public int doSomething(Input input1, Input input2){
            return returnValue;
        }
    };
    
  • 1

    我想知道何时使用静态方法?

    • static 方法的一个常见用途是访问 static 字段 .

    • 但是你可以拥有 static 方法,而不需要引用 static 变量 . 没有引用 static 变量的Helper方法可以在一些java类中找到,比如java.lang.Math

    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
    
    • 另一个用例,我可以想到这些方法结合 synchronized 方法是在多线程中实现类级别锁定环境 .

    假如我有一个带有几个getter和setter的类,一个或两个方法,我希望这些方法只能在类的实例对象上调用 . 这是否意味着我应该使用静态方法?

    如果需要访问类的实例对象的方法,则您的方法应该是非静态的 .

    Oracle文档page提供了更多详细信息 .

    并非所有实例和类变量和方法的组合都是允许的:

    • 实例方法可以直接访问实例变量和实例方法 .

    • 实例方法可以直接访问类变量和类方法 .

    • 类方法可以直接访问类变量和类方法 .

    • 类方法无法直接访问实例变量或实例方法 - 它们必须使用对象引用 . 此外,类方法不能使用this关键字,因为没有要引用的实例 .

  • 3

    java中的静态方法属于该类(不是它的实例) . 它们不使用实例变量,通常从参数中获取输入,对其执行操作,然后返回一些结果 . Instances方法与对象相关联,顾名思义,它可以使用实例变量 .

相关问题