답변:
하나의 규칙 : "자체가 아직 구성되지 않은 경우에도이 메서드를 호출하는 것이 합리적입니까?" 그렇다면 확실히 정적이어야합니다.
따라서 클래스 Car
에는 메소드가있을 수 있습니다.
double convertMpgToKpl(double mpg)
... 누구도 빌드하지 않은 경우에도 35mpg가 변환되는 것을 알고 싶을 수 있기 때문에 정적 Car
입니다. 그러나이 방법 (특정의 효율성을 설정 Car
) :
void setMileage(double mpg)
... Car
어떻게 구성 되기 전에 메소드를 호출 할 수 없기 때문에 정적 일 수 없습니다 .
(그렇지만, 그 반대는 항상 사실이 아닙니다. 때로는 두 개의 Car
객체 를 포함하는 메소드가있을 수 있으며 여전히 정적이기를 원할 수 있습니다.
Car theMoreEfficientOf( Car c1, Car c2 )
이것은 비 정적 버전으로 변환 될 수 있지만 일부는 "권한있는"선택 Car
이 더 중요하지 않기 때문에 호출자가 Car
호출 할 객체로 하나를 선택하도록 강요해서는 안된다고 주장 합니다 방법에. 이 상황은 모든 정적 메소드 중 상당히 작은 부분을 차지합니다.)
Car#isMoreEfficientThan(Car)
. 넥타이로 돌아 오는 차가 임의적이지 않다는 장점이 있습니다. 메소드의 제목에 의해 넥타이로 반환되는 것이 분명합니다.
다음 시나리오에서만 정적 메소드를 정의하십시오.
정적 메소드를 사용해야하는 몇 가지 유효한 이유가 있습니다.
성능 : 일부 코드를 실행하고 추가 객체를 인스턴스화하지 않으려면 정적 메소드로 입력하십시오. JVM은 또한 정적 메소드를 많이 최적화 할 수 있습니다 (정적 메소드는 빠르지 만 소스를 찾을 수 없으므로 JVM에서 사용자 정의 명령이 필요하지 않다고 선언하는 James Gosling을 읽었습니다. 그것은 완전히 거짓 일 수 있습니다). 그렇습니다. 미세 최적화이며 필요하지 않을 것입니다. 그리고 우리 프로그래머들은 필요하지 않은 것들이 시원하기 때문에 절대하지 않습니다.
실용성 : new Util().method(arg)
, call Util.method(arg)
또는 method(arg)
정적 가져 오기 대신에 . 더 쉽고 짧습니다.
메소드 추가 : 실제로 클래스 클래스에 removeSpecialChars()
인스턴스 메소드 를 갖기를 원했지만 거기에 없습니다 (프로젝트의 특수 문자가 다른 프로젝트의 문자와 다를 수 있기 때문에), 추가 할 수 없습니다 (Java 이후) 제정신입니다), 그래서 당신은 유틸리티 클래스를 만들고 removeSpecialChars(s)
대신에 호출s.removeSpecialChars()
. 단.
순도 : 몇 가지 예방 조치를 취하면 정적 메소드는 순수한 함수가됩니다 . 즉, 의존하는 유일한 것은 매개 변수입니다. 데이터 입력, 데이터 출력 상속에 대한 걱정이 없기 때문에 읽기 쉽고 디버그하기 쉽습니다. 인스턴스 메소드로도 수행 할 수 있지만 컴파일러는 정적 메소드 (인스턴스 속성에 대한 참조를 허용하지 않거나 메소드를 재정의하는 등)를 사용하여 조금 더 도움을 줄 것입니다.
싱글 톤을 만들려면 정적 메서드를 만들어야하지만 그렇지 않습니다. 두 번 생각하십시오.
더 중요한 것은 왜 정적 메서드를 만들고 싶지 않습니까? 기본적으로 다형성은 창 밖으로 나옵니다 . 메소드를 재정의 하거나 인터페이스 (Java 8 이전) 에서 선언 할 수 없습니다 . 디자인에서 많은 유연성이 필요합니다. 또한 state 가 필요한 경우 조심하지 않으면 많은 동시성 버그 및 / 또는 병목 현상이 발생합니다.
Misko의 기사를 읽은 후 정적 관점은 테스트 관점에서 좋지 않다고 생각합니다 . 대신 팩토리 가 있어야 합니다 ( Guice 와 같은 종속성 주입 도구를 사용 중일 수 있습니다 ).
"내가 하나만 가지고 있는지 확인하는 방법"이라는 문제는 아주 좋은 단계입니다. 기본에서 단일 ApplicationFactory 만 인스턴스화하고 결과적으로 모든 싱글 톤의 단일 인스턴스 만 인스턴스화합니다.
정적 메서드의 기본 문제는 절차 코드라는 것입니다. 절차 코드를 단위 테스트하는 방법을 모르겠습니다. 단위 테스트에서는 응용 프로그램을 개별적으로 인스턴스화 할 수 있다고 가정합니다. 인스턴스화하는 동안 실제 종속성을 대체하는 모의 / 친구와 종속성을 연결합니다. 절차 적 프로그래밍을 사용하면 객체가 없으므로 코드와 데이터가 분리되므로 "와이어"가 없습니다.
Math.abs()
하거나 Arrays.sort()
, 심지어 방법을 수행 할 수 있습니다 로 모든 종속성을 통과 , 나는 어떻게 것 이제까지 방해 단위 테스트가 표시되지 않습니다. 간단한 경험 법칙은 다음과 같습니다. 절차 적 논리를 모방해야 할 이유가 있다면 정적 방법으로 넣지 마십시오. 나는 밖으로 조롱하는 이유가 결코 Arrays.sort()
나 Math.abs()
.
static
방법은 호출 할 수 있도록 모든 개체를 필요로하지 않는 방법의 한 가지 유형의 초기화 할 것입니다. Java static
의 main
함수에서 사용되는 것을 보셨습니까 ? 객체가 생성되지 않은 상태에서 프로그램 실행이 시작됩니다.
다음 예제를 고려하십시오.
class Languages
{
public static void main(String[] args)
{
display();
}
static void display()
{
System.out.println("Java is my favorite programming language.");
}
}
정적 메소드는 인스턴스와 연관되지 않습니다. 그들은 수업에 속합니다. 정적 메소드는 두 번째 예입니다. 인스턴스 메소드가 첫 번째입니다.
어떤 방법으로도 정적 키워드를 적용하면 정적 방법이라고합니다.
// 모든 객체의 공통 속성을 변경하는 프로그램 (정적 필드).
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
정적 메소드는 클래스에서 호출되어야하고 인스턴스 메소드는 클래스의 인스턴스에서 호출되어야합니다. 그러나 그것은 실제로 무엇을 의미합니까? 다음은 유용한 예입니다.
자동차 클래스에는 Accelerate ()라는 인스턴스 메소드가있을 수 있습니다. 자동차가 실제로 존재하는 경우 (구성된 경우)에만 자동차를 가속 할 수 있으므로 이것이 인스턴스 방법입니다.
자동차 클래스에는 GetCarCount ()라는 count 메소드가있을 수도 있습니다. 생성 된 (또는 생성 된) 총 자동차 수를 반환합니다. 자동차가 구성되지 않은 경우이 메서드는 0을 반환하지만 여전히 호출 할 수 있어야하므로 정적 메서드 여야합니다.
실제로 클래스에서 정적 속성과 메서드를 사용합니다. 프로그램을 실행할 때까지 프로그램의 일부를 사용해야 할 때 프로그램이 실행될 때까지 있어야합니다. 그리고 정적 속성을 조작하려면 인스턴스 변수의 일부가 아니기 때문에 정적 메서드가 필요하다는 것을 알고 있습니다. 정적 메서드가 없으면 정적 속성을 조작하는 데 시간이 많이 걸립니다.
정적 메소드는 오브젝트에서 호출 할 필요가 없으며,이를 사용할 때입니다. 예 : Main ()은 정적이며 호출 할 객체를 만들지 않습니다.
다음과 같은 경우 정적 방법을 사용할 수 있습니다
인스턴스에 대한 조치를 수행하지 않으려는 경우 (유틸리티 메소드)
이 게시물의 위의 답변 중 일부에서 언급했듯이 마일을 킬로미터로 변환하거나 화씨에서 섭씨로 또는 그 반대로 온도를 계산합니다. 정적 메소드를 사용하는 이러한 예제를 사용하면 힙 메모리에서 완전히 새로운 객체를 인스턴스화 할 필요가 없습니다. 아래를 고려하십시오
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)
간단한 기능으로 사용하고 싶습니다. 입력이 명시 적으로 전달되어 결과 데이터를 반환 값으로 가져옵니다. 상속, 객체 인스턴스화는 그림으로 나오지 않습니다. 간결하고 읽기 쉬운 .
참고 : 정적 메소드의 테스트 가능성에 반대하는 사람들은 거의 없지만 정적 메소드도 테스트 할 수 있습니다! jMockit을 사용하면 정적 메소드를 조롱 할 수 있습니다. 테스트 가능성 . 아래 예 :
new MockUp<ClassName>() {
@Mock
public int doSomething(Input input1, Input input2){
return returnValue;
}
};
정적 메소드를 언제 사용해야하는지 궁금합니다.
static
메소드 의 일반적인 용도 는 static
필드 에 액세스하는 것 입니다.그러나 변수 static
를 참조하지 않고 메소드 를 가질 수 있습니다 static
. static
변수 를 참조하지 않는 헬퍼 메소드 는 java.lang.Math 와 같은 일부 Java 클래스에서 찾을 수 있습니다.
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
다른 유스 케이스에서는 이러한 메소드를 메소드와 결합하여 synchronized
멀티 스레드 환경에서 클래스 레벨 잠금을 구현하는 것으로 생각할 수 있습니다.
getter와 setter가 몇개 인 클래스, 메소드 또는 두 개가 있고 클래스의 인스턴스 객체에서만 해당 메소드를 호출 할 수 있기를 원한다고 가정하십시오. 이것이 정적 메소드를 사용해야 함을 의미합니까?
클래스의 인스턴스 객체에서 메소드에 액세스해야하는 경우 메소드는 정적이 아니어야합니다.
Oracle 설명서 페이지에 자세한 내용이 있습니다.
인스턴스 및 클래스 변수 및 메소드의 모든 조합이 허용되는 것은 아닙니다.
A common use for static methods is to access static fields.
논쟁이 아닙니다.
코드에서 메소드를 호출하는 객체를 작성하지 않으려는 경우 해당 메소드를 정적으로 선언하십시오. 정적 메소드는 호출 할 인스턴스가 필요하지 않지만 여기서 catch는 모든 정적 메소드가 JVM에 의해 자동으로 호출되는 것은 아닙니다. 이 특권은 런타임시 Java가 main () "public static void main [String ... args]"메소드 만 사용합니다. 이는 런타임에 JVM에서 시작점으로 찾은 Signature public "static"void main [] 메소드입니다. 코드 실행을 시작하십시오.
예:
public class Demo
{
public static void main(String... args)
{
Demo d = new Demo();
System.out.println("This static method is executed by JVM");
//Now to call the static method Displ() you can use the below methods:
Displ(); //By method name itself
Demo.Displ(); //By using class name//Recommended
d.Displ(); //By using instance //Not recommended
}
public static void Displ()
{
System.out.println("This static method needs to be called explicitly");
}
}
출력 :-이 정적 메소드는 JVM에 의해 실행됩니다.이 정적 메소드를 명시 적으로 호출해야합니다.이 정적 메소드를 명시 적으로 호출해야합니다.이 정적 메소드를 명시 적으로 호출해야합니다.