your programing

자바 : 정적 메서드를 사용하는 경우

lovepro 2020. 9. 28. 09:47
반응형

자바 : 정적 메서드를 사용하는 경우


정적 메서드를 언제 사용할지 궁금합니다. 몇 개의 getter와 setter가있는 클래스, 한두 개의 메서드가 있고 해당 메서드가 해당 클래스의 인스턴스 개체에서만 호출 가능하도록하고 싶습니다. 이것은 정적 메서드를 사용해야 함을 의미합니까?

예 :

Obj x = new Obj();
x.someMethod

또는

Obj.someMethod

(이게 정적 인 방법인가요?)

나는 오히려 혼란스러워!


한 가지 경험 법칙 : "아직 Obj가 생성되지 않은 경우에도이 메서드를 호출하는 것이 합리적입니까?"라고 자문 해보십시오. 그렇다면 확실히 정적이어야합니다.

그래서 클래스에서 정적 Car메서드 double convertMpgToKpl(double mpg)를 가질 수 있습니다. 왜냐하면 아무도 Car를 만들지 않았더라도 35mpg가 무엇으로 변환되는지 알고 싶을 수 있기 때문입니다. 그러나 void setMileage(double mpg)(특정 Car의 효율성을 설정하는) Car가 생성되기 전에 메서드를 호출하는 것은 상상할 수 없기 때문에 정적 일 수 없습니다.

(Btw, 그 반대가 항상 사실은 아닙니다. 때로는 두 개의 Car객체 를 포함하는 메서드가 있지만 여전히 정적이기를 원할 수 있습니다. 예 : Car theMoreEfficientOf( Car c1, Car c2 )이것은 비 정적 버전으로 변환 될 수 있지만 일부는 Car가 더 중요한 "특권"선택이 아니므로 호출자가 메서드를 호출 할 개체로 Car 하나를 선택하도록 강요해서는 안됩니다.이 상황은 모든 정적 메서드의 매우 작은 부분을 차지합니다. 그러나.)


다음 시나리오에서만 정적 메소드를 정의하십시오.

  1. 유틸리티 클래스를 작성 중이고 변경되지 않아야하는 경우.
  2. 메서드가 인스턴스 변수를 사용하지 않는 경우.
  3. 작업이 인스턴스 생성에 종속되지 않는 경우.
  4. 모든 인스턴스 메서드에서 쉽게 공유 할 수있는 코드가있는 경우 해당 코드를 정적 메서드로 추출합니다.
  5. 메서드의 정의가 변경되거나 재정의되지 않을 것이라고 확신하는 경우. 정적 메서드는 재정의 할 수 없습니다.

정적 메서드를 사용하는 몇 가지 유효한 이유가 있습니다.

  • 성능 : 일부 코드가 실행되기를 원하고이를 위해 추가 개체를 인스턴스화하지 않으려면 정적 메서드에 삽입합니다. JVM은 또한 정적 메소드를 많이 최적화 할 수 있습니다 (정적 메소드는 빠르지 만 소스를 찾을 수 없기 때문에 JVM에서 사용자 정의 명령이 필요하지 않다고 선언 한 James Gosling을 한 번 읽은 적이 있다고 생각합니다. 완전히 거짓 일 수 있습니다). 예, 이것은 마이크로 최적화이며 아마도 필요하지 않을 것입니다. 그리고 우리 프로그래머는 그들이 멋져서 불필요한 일을하지 않습니다.

  • 실용성 : new Util().method(arg), call Util.method(arg), 또는 method(arg)정적 가져 오기 대신 . 더 쉽고 짧습니다.

  • 메소드 추가 : String 클래스에 removeSpecialChars()인스턴스 메소드 가 있기를 원했지만 거기에 없습니다 (프로젝트의 특수 문자가 다른 프로젝트의 특수 문자와 다를 수 있기 때문에 그렇지 않아야 함), 추가 할 수 없습니다 (Java 이후 다소 정상적 임) 유틸리티 클래스를 만들고 removeSpecialChars(s)대신 s.removeSpecialChars(). 단.

  • 순도 : 몇 가지 예방 조치를 취하면 정적 메서드는 순수한 함수가됩니다 . 즉, 매개 변수 만 의존합니다. 데이터 입력, 데이터 출력. 걱정할 상속 문제가 없기 때문에 읽기 및 디버깅이 더 쉽습니다. 인스턴스 메서드로도 할 수 있지만 컴파일러는 정적 메서드 (인스턴스 속성에 대한 참조를 허용하지 않고 메서드를 재정의하는 등)로 조금 더 도움을 줄 것입니다.

싱글 톤을 만들려면 정적 메서드도 만들어야하지만 ...하지 마세요. 두 번 생각 해보세요.

이제 더 중요한 것은 정적 메서드를 만들고 싶지 않습니까? 기본적으로 다형성은 창 밖으로 나갑니다 . 메서드를 재정의 하거나 인터페이스 (Java 8 이전) 에서 선언 할 수 없습니다 . 디자인에서 많은 유연성이 필요합니다. 또한 state 가 필요한 경우주의하지 않으면 많은 동시성 버그 및 / 또는 병목 현상이 발생합니다.


Misko의 기사를 읽은 후 테스트 관점에서 정적 메서드 가 나쁘다고 생각합니다 . 대신 팩토리 가 있어야 합니다 ( Guice 와 같은 종속성 주입 도구를 사용할 수 있음 ).

내가 하나만 가지고 있는지 어떻게 확인합니까?

오직 하나만 가지고있다“어떻게 내가 하나만 가지게 할 수 있는가”라는 문제는 멋지게 회피된다. 메인에서 단일 ApplicationFactory 만 인스턴스화하므로 결과적으로 모든 싱글 톤의 단일 인스턴스 만 인스턴스화됩니다.

정적 메서드의 기본적인 문제는 절차 적 코드라는 것입니다.

정적 메서드의 기본적인 문제는 절차 적 코드라는 것입니다. 절차 코드를 단위 테스트하는 방법을 모르겠습니다. 단위 테스트에서는 애플리케이션의 일부를 격리하여 인스턴스화 할 수 있다고 가정합니다. 인스턴스화하는 동안 실제 종속성을 대체하는 mocks / friendlies와 종속성을 연결합니다. 절차 적 프로그래밍에서는 객체가없고 코드와 데이터가 분리되어 있기 때문에 "연결"할 필요가 없습니다.


static방법은 호출 할 수 있도록 모든 개체를 필요로하지 않는 방법의 한 가지 유형의 초기화 할 것입니다. Java staticmain함수에서 사용되는 것을 보셨습니까 ? 프로그램 실행은 개체가 생성되지 않은 상태에서 시작됩니다.

다음 예를 고려하십시오.

 class Languages 
 {
     public static void main(String[] args) 
     {
         display();
     }

     static void display() 
     {
         System.out.println("Java is my favorite programming language.");
     }
  }

Java의 정적 메소드는 클래스에 속합니다 (그 인스턴스가 아님). 인스턴스 변수를 사용하지 않으며 일반적으로 매개 변수에서 입력을 받고 이에 대한 작업을 수행 한 다음 일부 결과를 반환합니다. 인스턴스 메서드는 개체와 연결되며 이름에서 알 수 있듯이 인스턴스 변수를 사용할 수 있습니다.


아니요, 정적 메서드는 인스턴스와 연결되지 않습니다. 그들은 수업에 속합니다. 정적 메서드는 두 번째 예입니다. 인스턴스 메서드가 첫 번째입니다.


어떤 방법 으로든 정적 키워드를 적용하면이를 정적 방법이라고합니다.

  1. 정적 메서드는 클래스의 객체가 아닌 클래스에 속합니다.
  2. 클래스의 인스턴스를 만들 필요없이 호출되는 정적 메서드입니다.
  3. 정적 메소드는 정적 데이터 멤버에 액세스 할 수 있으며 그 값을 변경할 수 있습니다.
  4. 정적 메서드는 클래스 dot static name의 이름을 사용하여 액세스 할 수 있습니다. . . 예 : Student9.change ();
  5. 클래스의 비 정적 필드를 사용하려면 비 정적 메서드를 사용해야합니다.

// 모든 객체 (정적 필드)의 공통 속성을 변경하는 프로그램.

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


정적 메서드는 인스턴스와 연결되어 있지 않으므로 클래스의 비 정적 필드에 액세스 할 수 없습니다.

메서드가 클래스의 필드 (또는 정적 필드 만)를 사용하지 않는 경우 정적 메서드를 사용합니다.

클래스의 비 정적 필드가 사용되는 경우 비 정적 메서드를 사용해야합니다.


Static methods should be called on the Class, Instance methods should be called on the Instances of the Class. But what does that mean in reality? Here is a useful example:

A car class might have an instance method called Accelerate(). You can only Accelerate a car, if the car actually exists (has been constructed) and therefore this would be an instance method.

A car class might also have a count method called GetCarCount(). This would return the total number of cars created (or constructed). If no cars have been constructed, this method would return 0, but it should still be able to be called, and therefore it would have to be a static method.


Actually, we use static properties and methods in a class, when we want to use some part of our program should exists there until our program is running. And we know that, to manipulate static properties, we need static methods as they are not a part of instance variable. And without static methods, to manipulate static properties is time consuming.


Use a static method when you want to be able to access the method without an instance of the class.


Static methods don't need to be invoked on the object and that is when you use it. Example: your Main() is a static and you don't create an object to call it.


Static methods and variables are controlled version of 'Global' functions and variables in Java. In which methods can be accessed as classname.methodName() or classInstanceName.methodName(), i.e. static methods and variables can be accessed using class name as well as instances of the class.

Class can't be declared as static(because it makes no sense. if a class is declared public, it can be accessed from anywhere), inner classes can be declared static.


Static: Obj.someMethod

Use static when you want to provide class level access to a method, i.e. where the method should be callable without an instance of the class.


Static methods can be used if

  • One does not want to perform an action on an instance (utility methods)

    As mentioned in few of above answers in this post, converting miles to kilometers, or calculating temperature from Fahrenheit to Celsius and vice-versa. With these examples using static method, it does not need to instantiate whole new object in heap memory. Consider below

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

    the former creates a new class footprint for every method invoke, Performance, Practical. Examples are Math and Apache-Commons library StringUtils class below:

    Math.random()
    Math.sqrt(double)
    Math.min(int, int)
    StringUtils.isEmpty(String)
    StringUtils.isBlank(String)
    
  • One wants to use as a simple function. Inputs are explictly passed, and getting the result data as return value. Inheritence, object instanciation does not come into picture. Concise, Readable.

NOTE: Few folks argue against testability of static methods, but static methods can be tested too! With jMockit, one can mock static methods. Testability. Example below:

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

Static methods are the methods in Java that can be called without creating an object of class. It is belong to the class.

We use static method when we no need to be invoked method using instance.


I am wondering when to use static methods?

  1. A common use for static methods is to access static fields.
  2. But you can have static methods, without referencing static variables. Helper methods without referring static variable can be found in some java classes like java.lang.Math

    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
    
  3. The other use case, I can think of these methods combined with synchronized method is implementation of class level locking in multi threaded environment.

Say if I have a class with a few getters and setters, a method or two, and I want those methods only to be invokable on an instance object of the class. Does this mean I should use a static method?

If you need to access method on an instance object of the class, your method should should be non static.

Oracle documentation page provides more details.

Not all combinations of instance and class variables and methods are allowed:

  1. Instance methods can access instance variables and instance methods directly.
  2. Instance methods can access class variables and class methods directly.
  3. Class methods can access class variables and class methods directly.
  4. Class methods cannot access instance variables or instance methods directly—they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to.

A static method has two main purposes:

  1. For utility or helper methods that don't require any object state. Since there is no need to access instance variables, having static methods eliminates the need for the caller to instantiate the object just to call the method.
  2. For the state that is shared by all instances of the class, like a counter. All instance must share the same state. Methods that merely use that state should be static as well.

In eclipse you can enable a warning which helps you detect potential static methods. (Above the highlighted line is another one I forgot to highlight)

eclipse setting


When static methods can be good?

There are only two situations when static methods or variables are being used and it's not an abomination.

  1. Declaring a true global constant, not a global variable. A global constant. Example: Math.PI. This is a fair shorthand for really saying that there is one instance of the universe, and that universe singleton contains a mathematical concept singleton in which there is a property PI which does not change. This concept seems strange to us because we are used to not thinking about PI in the context of object oriented responsibility. It would become more obvious if we were designing some strange game where there were alternate universes with different mathematical concepts and constants.
  2. Object creation. Static methods are a valuable and valid method of object creation. Overloaded constructors that take different arguments are not very clear and are often made clearer by replacing them with a static constructor.

When static methods are bad?

  1. One way to think about static methods is as global procedures. Essentially a static method can be called anywhere from anywhere. It just pretends to be part of a class, when really the class is only used as a “tag”, which organizes the method by some logical division. I look at static methods in these terms, because creating global procedures is the exact opposite of object oriented design.

  2. Another major problem with static methods is the testability. Testability is a big deal when building software. Static methods are notoriously difficult to test, especially when they create new instances of concrete classes. If you have ever worked in legacy code and tried to write a unit test for a static method, you know my pain.

  3. Static methods also are not polymorphic. If you create a static method on a class, there is no overriding that behavior. You are stuck with a hard coded reference to that implementation.

Final words

So just remember when you create a static method to think about it carefully. I am not advocating never using them. I am advocating having a really good reason and checking first to see if the static method really belongs to another class where it can use state information.

참고URL : https://stackoverflow.com/questions/2671496/java-when-to-use-static-methods

반응형