정적 메소드가 메소드로 간주되는 이유는 무엇입니까?


135

코스에 대한 일부 코드에 대한 설명을 작성 중이며 실수로 단어 methodfunction상호 교환 적으로 사용 하고 있습니다. 나는 돌아가서 문구를 고치기로 결정했지만 내 이해에 구멍이났다.

내가 이해 한 바에 따르면, 서브 루틴은 function클래스의 인스턴스에 영향을 미치지 않는 경우 (효과는 명시적인 입력 / 출력으로 제한됨)이고 method클래스의 인스턴스에서 작동하는 경우입니다 ( 불완전한 인스턴스에 대한 부작용).

이 주제에 대한 좋은 토론이 있습니다 . 허용 된 답변의 정의에 따르면 method인스턴스는 암시 적으로 전달되지 않으며 인스턴스의 멤버에 액세스 할 수 없으므로 정적 은 실제로 함수 여야합니다.

그러나 이것을 염두에두고 methods실제로 정적이어야하지 않습니까?

그들의 정의에 따라 그들은 클래스의 특정 인스턴스에 대해 행동하지 않습니다. 그들은 관계 때문에 수업에 "연결"되어 있습니다. 정적 서브 루틴을 "메소드"( Oracle , Fredosaurus , ProgrammingSimplified ) 로 지칭하는 잘 보이는 사이트를 보았 으므로 모두 용어를 간과하거나 뭔가 빠졌습니다 (내 추측은 후자입니다) .

올바른 문구를 사용하고 싶습니다.
아무도 이것을 정리할 수 있습니까?


2
나는 항상 그것이 PHP의 함수이고 Java의 메소드라고 생각했습니다. 기본적으로 다른 이름을 가진 동일한 것
JK

19
이론적 인 컴퓨터 과학과 언어가 그것을 적용하는 방법에는 차이가 있습니다. JLS는 구별하지 않고이를 메소드라고합니다.
Jeroen Vannevel


2
차이 있는 파이썬에서 "함수"와 "방법"의 정의를 살펴 보는 것이 흥미로울 수 있습니다 . 기본적으로 함수는 기호 테이블과 호출 규칙이있는 코드 덩어리입니다. 클래스에 함수를 넣으면 얻을 수 있습니다. 파이썬을 아는 사람들조차도 그 차이는 미묘합니다.
David Z

2
이론을 배우고있을 때 함수가 값을 반환하고 프로시 저는 그렇지 않다는 것을 알게되었습니다. 그런 다음 Java 호출 함수 및 프로 시저 메소드를 배웠습니다. 이제 기능적인 programmjng를 시도하고 있으며 기능이 dem 등합니다. 용어는 문맥 상 의미를 변경합니다.
emory

답변:


123

8.4.3.2의 인용문 이 도움 이 될 수 있습니다.

선언 된 메소드를 클래스 메소드static 라고합니다 .

선언되지 않은 메소드를 인스턴스 메소드 [...] static라고합니다 .

  • 클래스 메소드 : 클래스와 연관됩니다.
  • 인스턴스 메소드 : 인스턴스와 연관됩니다.

Java는 단지 "객체 지향"을 원합니다. 또한 정적 메소드는 상태를 포함 할 수있는 주변 범위에 액세스 할 수 있습니다. 어떤면에서 클래스는 객체 자체와 같습니다.


즉, "함수"는 Java에서 실행 단위로 기술적으로 정확하지만 모든 Java 함수가 클래스 또는 인터페이스의 일부이기 때문에 거의 모든 Java에서 선호되는 명명법은 "방법"입니다 (람다 제외). 내가 모르는 다른 것들).
Shotgun Ninja

1
람다는 실제로 @FunctionalInterface주석이 있고 내부 에 1 개의 메소드가있는 익명의 내부 클래스입니다 . 람다는 단지 구문 설탕이며 그 점에서 새로운 것은 없습니다.
Adam Arold

1
@AdamArold Lambdas는 익명의 내부 클래스보다 약간 더 환상적입니다. 예를 들어, 캡처하지 않는 람다는 특정 식에 대한 여러 평가에서 인스턴스를 공유 할 수 있습니다. (그러나 당신은 그것들이 궁극적으로 정적 및 인스턴스 메소드로 컴파일됩니다.)
Radiodef

@Radiodef 어쩌면 "람다 식을 포함하는 파일 이외의 파일을 변경하지 않고 모든 람다 식을 동일한 람다식이 아닌 다른 식으로 바꿀 수 있습니다."
user253751

4
나는 당황. 나는 Scala에서 왔으며 여전히 클래스 자체가 객체와 같다는 사실을 놓쳤습니다. 감사합니다.
Carcigenicate

80

간단한 대답은 Java가 모든 것을 "방법"이라고 부르기로 결정했을 때 이론적 컴퓨터 과학의 기능과 방법의 구별에 신경 쓰지 않았다는 것입니다.


3
맞습니다. Java 7까지는 언어 사양
Erwin Bolwidt

4
이 답변의 단순함을 좋아하는만큼 Radiodef의 답변은 클래스 자체가 객체로 작동하는 핵심 요점을 언급하기 때문에 궤도에 더 가깝습니다. 그래도 감사합니다.
Carcigenicate

2
흥미롭게도 이것은 기능과 서브 루틴을 구분하지 않는 이전 언어의 결정과 유사합니다.
Random832

4
이 답변이 너무 많은 투표를 받았다는 것이 불쾌하게 놀랍습니다. 첫째,이 답변은 클래스 메소드가 존재하지 않는 척합니다. 둘째, 이것은 Java로 도입 된 개념이 아닙니다. 예를 들어 스몰 토크에는 이미 클래스 메소드가 존재했는데, 이는 자바가되기 전에 수십 년 동안 존재했다.
Malcolm

1
@ Malcolm 동의합니다. 다른 답변을 고려한 후에 이것은 잘못된 것 같습니다. 그들이 정말로 신경 쓰지 않고 정확하게 이름을 짓지 않으면 Java 제작자에게는 무관심하지 않습니다.
Carcigenicate

26

정적 메소드는 정확히 기능하지 않으며 차이는 미묘하지만 중요합니다.

주어진 입력 매개 변수 만 사용하는 정적 방법 본질적으로 함수입니다.

그러나 정적 메소드는 정적 변수 및 기타 정적 함수 (정적 변수를 사용하여)에 액세스 할 수 있으므로 정적 메소드 는 기본적으로 stateless 함수와 기본적으로 다른 상태 를 가질 수 있습니다 . (부록 : 프로그래머는 종종 "함수"를 정의로 사용하는 것이 그렇게 엄격하지는 않지만 컴퓨터 과학의 엄격한 기능은 입력 매개 변수에만 액세스 할 수 있습니다). 따라서 정적 필드에 액세스하는 경우를 정의하면 정적 메소드가 항상 함수라고 말하는 것이 유효하지 않습니다.

"정적 방법"의 사용을 정당화하는 또 다른 차이점은 C에서 정의 할 수있는 전역 함수와 전역 변수는 어디에서나 액세스 할 수 있다는 것입니다. 정적 메서드가 포함 된 클래스에 액세스 할 수 없으면 메서드도 액세스 할 수 없습니다. 따라서 "정적 방법"은 전역 기능과 달리 설계 상 범위가 제한됩니다.


2
나는이 답변을 좋아하지만 몇 가지를 더 잘 이해하고 싶습니다. 이것이 함수 대 방법보다는 "순수"대 "부작용"기능이 아닌가? 아니면 부작용으로 인한 방법입니까? 나는 단지 여기에서 브레인 스토밍하고있다.
Nadir Sampaoli

2
이 대답은 옳습니다. 그러나 많은 (대부분의) 언어의 함수가 전역 변수에 액세스 할 수 있다고 주장 할 수 있으므로 종종 상태 비 저장 (동일한 입력, 동일한 출력)이 아닙니다. 그리고 Java 정적 메소드의 경우 클래스 변수에 액세스하는 것은 클래스 인스턴스가 네임 스페이스의 일종 인 "전역"(예 : 함수 / 메소드에 로컬이 아닌) 변수에 액세스하는 것과 동등한 것으로 간주 될 수 있습니다.
leonbloy

1
@leonbloy Pure Haskell과 같은 함수형 프로그래밍 언어 는 완전히 상태가 없습니다. 전역 변수라고 할 수있는 것은 없습니다.
Thorsten S.

17

Java에서 사용자 정의 클래스는 실제로 java.lang.Class 서브 클래스의 인스턴스입니다.

이런 의미에서 정적 메소드 개념적 클래스의 인스턴스에 첨부됩니다. java.lang.Class 서브 클래스의 인스턴스에 첨부됩니다.

이를 염두에두고 "클래스 메소드"(Java의 정적 메소드의 대체 이름)라는 용어가 이해되기 시작합니다. "클래스 메소드"라는 용어는 Objective C, Smalltalk 및 JLS 등 여러 곳에서 찾을 수 있습니다.


이 서브 클래스의 인스턴스를 두 개 가질 수 있습니까?
Random832

물론 클래스를 다른 클래스 로더에로드 할 수 있습니다 ( "CustomClass를 CustomClass로 캐스트 할 수 없음"메시지와 함께 ClassCastExceptions가 발생하는 이유).
dunni

2
@ Random832-종류. 각 인스턴스마다 별도의 클래스 로더가있는 한 동일한 JVM에 동일한 클래스 서브 클래스의 두 개 이상의 인스턴스가있을 수 있습니다. 클래스 로더 당 동일한 클래스 서브 클래스를 두 번 이상 인스턴스화 할 수 없습니다. 약간 혼란스럽고 클래식 OO 개념과 유사 하여이 시점에서 약간 얇아지기 시작합니다.
마이크 클라크

@MikeClark 내가 그렇게하면 정말 동일합니까? 마찬가지로 클래스 자체가 다른 인스턴스 인 경우에도 클래스 하위 클래스가 동일한 클래스입니까? 클래스 로더는 꽤 혼란 스럽습니다. 클래스에 대한 참조를 전달하여 같은 클래스의 다른 클래스 로더 인스턴스에서 클래스 클래스의 인스턴스에 대한 정적 메소드를 리플렉션없이 호출 할 수 있습니까? 그들이 다른 방법을 가지고 있다면 어떨까요?
Random832

1
@ Random832 "정렬?" 순전히 OO 이론의 관점에서 볼 때, 클래스의 두 인스턴스는 실제로 정확히 동일합니까? 동일한 클래스의 최소한 두 개의 동일한 인스턴스는 다른 주소를 갖습니다. 그렇지 않으면 어떻게 두 가지를 가질 수 있습니까? 무언가와 정확히 같은 유일한 것은 그 자체입니다.
마이크 클라크

11

컴퓨터 과학 기능 에서 정적 방법으로 명확하게 매핑됩니다. 그러나 클래스의 "메소드"는 "멤버"(필드 멤버, 메소드 멤버)와 같은 약간 일반적입니다. 같은 문구가 있습니다

데이터 멤버와 메서드 멤버에는 .x와 .x ()가 공존 할 수있는 두 개의 별도 네임 스페이스가 있습니다.

그 이유는 철학자 루트비히 위트 겐슈 타인 (Ludwig Wittgenstein)이 말했듯이 언어는 상황이 다른 도구입니다. "방법"은 위의 인용에서 "회원"을 분류하는 좋은 이름입니다.


9

당신의 생각은 옳고 말이됩니다. Java 커뮤니티에서 용어가 확립되지 않았습니다. 용어가 존재하는 이유를 이해하는 데 도움이되는 내부 내용을 설명하겠습니다.

Java는 클래스 기반 객체 지향 언어입니다. 메소드는 항상 클래스 또는 인스턴스의 멤버입니다 (이는 다른 프로그래밍 언어에도 유효한 일반 명령문입니다). 우리는 클래스와 인스턴스가 모두 객체라고 생각합니다.

인스턴스 방법 (동적)

클래스에서이 메소드를 직접 호출 할 수 없으므로 인스턴스를 작성해야합니다. 각 인스턴스는 해당 방법을 참조합니다. 서브 클래 싱 할 때와 정확히 동일한 메소드 서명으로 메소드 정의를 겹쳐 쓸 수 있습니다. 즉 참조는 다른 메소드 (서명은 동일하지만 메소드 본문이 다를 수 있음)를 가리 킵니다. 이 방법은 동적입니다.

수업 방법 (정적)

클래스에서 직접이 메소드를 호출 할 수 있습니다. 즉, 해당 클래스의 인스턴스를 작성할 필요가 없습니다. 전체 프로그램에서 해당 메소드의 글로벌 정의는 하나만 있습니다. 전체 프로그램에 대해 하나의 정의 만 유효하므로 메소드가 정적으로 선언 된 경우 정확히 동일한 메소드 서명을 겹쳐 쓸 수 없습니다. 이 메소드는 클래스 객체 자체의 멤버이며 인스턴스는 해당 메소드에 대한 모든 동일한 고유 (및 수정) 참조를 갖습니다.


7

스칼라 를 니모닉으로 사용하는 또 다른 용어는 다음과 같습니다
. 스칼라 object에는 묵시적으로 정의 된 클래스의 싱글 톤 인스턴스가 있습니다.1 .

정의에 따라, object 메소드의 서브 루틴을 클래스의 단일 인스턴스에서 작동 할 때 호출 할 수 있습니다 .
또한 객체 는 클래스 A를 정의 하고 객체 A의 모든 메소드를 클래스 A의 정적 메소드 (Java와의 인터페이스 용)로 작성합니다 [2] .

따라서 Java 클래스 A의 정적 메소드는 스칼라 싱글 톤 인스턴스와 동일한 멤버에 액세스한다고 정의 할 수 있으며, 정의 에 따라 클래스 A의 (정적) 메소드 라고 할 수 있습니다 .


훌륭한 비교. 나는 스칼라를 알고 있으므로 object참조는 많은 의미가 있습니다. 감사합니다.
Carcigenicate

2

물론 주요 차이점은-메소드는 메소드 매개 변수뿐만 아니라 정적 필드를 사용할 수 있다는 것입니다. 그러나 다형성이 하나 더 있습니다! 클래스 A.doTheSameStaticMethod () 및 ClassB.doTheSameStaticMehod () 평가 결과는 클래스에 따라 다릅니다. 이 경우 기능이 작동하지 않습니다.


1

각 클래스에는 클래스의 서브 클래스 인스턴스 인 객체를 나타냅니다 Class. 정적 메소드는 실제로 이러한 오브젝트에서 Class 서브 클래스의 인스턴스 인 인스턴스 메소드입니다. 정적 필드 형태로 상태에 액세스 할 수 있으므로 단지 (상태 비 저장) 함수로 제한되지 않습니다. 그것들은 방법입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.