C 및 C ++ 배경에서 온, 나는 신중하게 사용 typedef
하는 것이 엄청나게 도움이된다는 것을 알았습니다 . Java 메커니즘, 패턴 또는 다른 효과적인 방법이든 Java에서 유사한 기능을 수행하는 방법을 알고 있습니까?
public interface ScopeFactory { <Scope extends Map<String, Object>> Scope create(...) throws Exception; }
C 및 C ++ 배경에서 온, 나는 신중하게 사용 typedef
하는 것이 엄청나게 도움이된다는 것을 알았습니다 . Java 메커니즘, 패턴 또는 다른 효과적인 방법이든 Java에서 유사한 기능을 수행하는 방법을 알고 있습니까?
public interface ScopeFactory { <Scope extends Map<String, Object>> Scope create(...) throws Exception; }
답변:
Java에는 기본 유형, 객체 및 배열이 있습니다. 타입 정의가 없습니다.
typedef
재정의 boolean
하기를 원한다고 생각 합니다 bool
.
typedef int PlayerID
확인 PlayerIDs 다른의 int와 상호 교환 사용하지 않는 확인하기 위해 컴파일러를 가능하게하는, 그리고 그것은 또한 인간에 대한 더 많은 읽을 수있는 코드를 만드는 . 기본적으로 열거 형과 같지만 제한된 값 집합이 없습니다.
typedef MegaLongTemplateClass<With, Many, Params> IsShorten;
.
typedef
되지 않게 할 수있게 해줍니다 "– 그런 것을 가능하게하지 않습니다. 유형에 대한 다른 이름 만 제공합니다.
int
있고로 변경해야하는 long
경우 ID로 작업하는 코드의 모든 위치에서 ID 를 변경해야하는 경우에도 유용합니다 . 이있는 경우 한 typedef
곳에서만 변경하면됩니다.
이것이 의미하는 바라면 typedef하려는 클래스를 간단히 확장 할 수 있습니다. 예를 들면 다음과 같습니다.
public class MyMap extends HashMap<String, String> {}
typedef
기사가 그 가짜 클래스에 대해 설명하는 문제는 없습니다 (그리고 그들은 매우 현실적입니다).
final
클래스 와 함께 사용할 수 없다는 것입니다 .
1.6에서 현재 Java에는 typedef가 없으며 최종 클래스 (Integer, Double 등)를 서브 클래스 할 수 없으므로 원하는 래퍼 클래스를 만드는 것이 가능합니다.
다른 사람들이 이전에 언급했듯이
Java에는 typedef 메커니즘이 없습니다.
나는 또한 일반적으로 "가짜 클래스"를 지원하지 않지만 여기에 일반적인 엄격한 규칙이 없어야합니다
.
Map<String, List<Integer>>
그 목적을 위해 서브 클래스를 갖는 것을 반드시 고려해야합니다.
고려할 수있는 또 다른 접근법은 예를 들어 코드에서 다음과 같은 감속을 갖는 것입니다.
//@Alias Map<String, List<Integer>> NameToNumbers;
그런 다음 코드에서 NameToNumbers를 사용하고 관련 Java 코드를 처리하고 생성하기위한 사전 컴파일러 태스크 (ANT / Gradle / Maven)가 있어야합니다.
나는이 답변의 독자들에게 이것이 이상하게 들릴지 모른다는 것을 알고 있지만, 이것은 JDK 5 이전에 "어노테이션"을 구현 한 프레임 워크의 수입니다. 이것은 lombok 프로젝트 가 수행하는 작업과 다른 프레임 워크입니다.
실제로 Javaland로 전달되는 typedef의 유일한 사용은 앨리어싱 즉, 같은 클래스에 여러 이름을 부여하는 것입니다. 즉, 클래스 "A"가 있고 "B"가 같은 것을 참조하기를 원합니다. C ++에서는 "typedef BA;"를 수행하게됩니다.
불행히도, 그들은 그것을 지원하지 않습니다. 그러나 관련된 모든 유형을 제어하면 라이브러리 수준에서 불쾌한 해킹을 당길 수 있습니다 .B를 A에서 확장하거나 B가 A를 구현하도록하십시오.
typedef
또한 일반적인 유형의 호출에 대한 별칭을 만들 도움이 될 것입니다. 예를 들면 다음과 같습니다. typedef A<Long,String> B;
(이것은 당신이 묘사 한 특별한 경우 일 수 있지만 아이디어의 매력을 조금 더 명확하게 보여줍니다).
real_t
에 double
와 bool
에 boolean
.
아마도 이것은 또 다른 가능한 교체 일 수 있습니다.
@Data
public class MyMap {
@Delegate //lombok
private HashMap<String, String> value;
}
myMap
유형의 인스턴스 를 정의 할 때 MyMap
마다을 myMapInstance.value.SomeOperation()
대신 입력하여 실제 HashMap에서만 조작 할 수 있기 때문에 이제 이것이 문제가된다고 생각하지 않습니다 myMapInstance.SomeOperation()
. 짜증나 지 않습니까?
다른 답변에서 언급했듯이 의사 타입 정의 반 패턴을 피해야합니다 . 그러나 typedef는이를 달성 할 수없는 방법이더라도 여전히 유용합니다. 동일한 Java 표현을 가진 다른 추상 유형을 구별하려고합니다. 암호 인 문자열과 주소를 나타내는 문자열 또는 오프셋을 나타내는 정수를 절대 값을 나타내는 문자열과 혼합하지 않으려 고합니다.
검사 프레임 워크는 이전 버전과 호환 방법으로 형식 정의를 정의 할 수 있습니다. 나는 같은 기본 클래스와 같은 int
최종 클래스 에서도 작동합니다 String
. 런타임 오버 헤드가 없으며 평등 테스트를 중단하지 않습니다.
제 타입 별칭과 형식 정의 검사기 프레임 워크 설명서는 필요에 따라 형식 정의를 만들 수있는 몇 가지 방법을 설명합니다.
Kotlin은 https://kotlinlang.org/docs/reference/type-aliases.html 유형 별칭을 지원합니다 . 타입과 함수 타입의 이름을 바꿀 수 있습니다.
경우에 따라 바인딩 주석이 원하는 것일 수 있습니다.
https://github.com/google/guice/wiki/BindingAnnotations
또는 Guice에 의존하고 싶지 않다면 일반적인 주석 만 가능합니다.
Typedef를 사용하면 항목을 암시 적으로 유형이 아닌 유형에 할당 할 수 있습니다. 어떤 사람들은 확장 기능으로이 문제를 해결하려고합니다. 이것이 왜 나쁜 생각인지에 대한 설명은 여기 IBM에서 읽으십시오.
편집 : 강력한 유형 유추가 유용한 것이지만 typedef
관리 언어로 추악한 머리를 키우는 것을 보지 않을 것이라고 생각 합니다.
편집 2 : C #에서는 소스 파일 맨 위에 이와 같은 using 문을 사용할 수 있습니다. 사용되므로 표시된 두 번째 항목을 수행 할 필요가 없습니다. 이름이 변경되는 유일한 시점은 스코프가 두 유형간에 이름 충돌을 일으키는 경우입니다. 이름 변경은 하나의 파일로 제한되며, 파일을 사용한 모든 변수 / 매개 변수 유형은 전체 이름으로 알려져 있습니다.
using Path = System.IO.Path;
using System.IO;
Java에서는 typedef가 필요하지 않습니다. 프리미티브를 제외한 모든 것이 객체입니다. 포인터는없고 참조 만 있습니다. 일반적으로 typedef를 사용하는 시나리오는 대신 객체를 만드는 인스턴스입니다.
UnmodifiableDirectedGraph<IncrediblyFancyEdgeType, IncrediblyFancyAbstractNode.EvenFancierConcreteNode>
또는 IncrediblyFancyGraph
? 나는 항상 정의를 참조하여 실제로 무엇이 무엇인지 알아낼 수 있습니다. 그렇게하면 나는 UnmodifiableDirectedGraph<IncrediblyFancyEdge,IncredilyFancyAbstractNode.SlightlyLessFancyConcreteNode>
지루함을 놓치지 않을 것입니다.
Enterprise
. 클래스 이름에는 단어가 포함되어 있지 않습니다 .