C ++에 typedef 키워드에 대한 Java 동등 또는 방법이 있습니까?


244

C 및 C ++ 배경에서 온, 나는 신중하게 사용 typedef하는 것이 엄청나게 도움이된다는 것을 알았습니다 . Java 메커니즘, 패턴 또는 다른 효과적인 방법이든 Java에서 유사한 기능을 수행하는 방법을 알고 있습니까?


6
typedef는 좋고 나쁘거나 많은 것들을 사용할 수 있습니다. typedef의 어떤 측면이 가치 있다고 생각하십니까? 그렇게하면 Java에서 유사한 효과를 얻는 방법이나 왜 Java에서 원하지 않는 일인지 말할 수 있습니다. 아래의 답변 모음은 저자가 좋아하는 (또는 가장 싫어하는) 용도에 대해 이야기하고 있다고 가정합니다.
PanCrit

3
나중에 클래스로 변환 할 수 있다면 네이티브 유형을 typedef하고 싶습니다. typedef IndexT int; 예를 들어. 나중에 IndexT를 클래스로 사용하려면 구현하고 typedef를 제거하십시오. 정보 숨기기에 도움이됩니다.
JR Lawhorne


1
나는 이것의 단점이 무엇인지 잘 모르겠지만 :public interface ScopeFactory { <Scope extends Map<String, Object>> Scope create(...) throws Exception; }
ScootyPuff

답변:


112

Java에는 기본 유형, 객체 및 배열이 있습니다. 타입 정의가 없습니다.


38
나는 대부분의 사람들이 typedef재정의 boolean하기를 원한다고 생각 합니다 bool.
Tomáš Zato-Reinstate Monica

66
TomášZato @ 나는 대부분의 사람들이 잘 모르지만, 내 경험, 그것은 같은 의미를 추가하기위한 유용 : typedef int PlayerID확인 PlayerIDs 다른의 int와 상호 교환 사용하지 않는 확인하기 위해 컴파일러를 가능하게하는, 그리고 그것은 또한 인간에 대한 더 많은 읽을 수있는 코드를 만드는 . 기본적으로 열거 형과 같지만 제한된 값 집합이 없습니다.
weberc2

76
@ TomášZato 또한 같은 긴 유형을 줄이는 데 유용합니다 typedef MegaLongTemplateClass<With, Many, Params> IsShorten;.
Alex Medveshchek 12

32
@ weberc2는 "컴파일러가 PlayerID를 다른 int와 호환 typedef되지 않게 할 수있게 해줍니다 "– 그런 것을 가능하게하지 않습니다. 유형에 대한 다른 이름 만 제공합니다.
emlai

7
예를 들어, 일부 유형의 ID가 int있고로 변경해야하는 long경우 ID로 작업하는 코드의 모든 위치에서 ID 를 변경해야하는 경우에도 유용합니다 . 이있는 경우 한 typedef곳에서만 변경하면됩니다.
자르도

101

이것이 의미하는 바라면 typedef하려는 클래스를 간단히 확장 할 수 있습니다. 예를 들면 다음과 같습니다.

public class MyMap extends HashMap<String, String> {}

5
나는 이것이 C에서 typedef를 사용하는 것보다 더 반 패턴인지 아닌지를 논할 것이다.
Zed

22
그것은 분명히- typedef기사가 그 가짜 클래스에 대해 설명하는 문제는 없습니다 (그리고 그들은 매우 현실적입니다).
Pavel Minaev

30
@Andreas_D : 링크가 수정되었습니다 : ibm.com/developerworks/java/library/j-jtp02216/index.html
Janus Troelsen

7
나는 typedef를 좋아하는 것과 같은 이유로 이것을 좋아합니다. 객체 컨테이너가있는 경우 typedef를 변경하여 컨테이너 유형을 쉽게 교체 할 수 있습니다. 또한 컨테이너를 최종 사용자에게 추상화 할 수도 있습니다 (때로는 바람직 함). 나는 보통 다른 클래스 안에서 이것을 할 것이다. 그래서 타입이 더 명확 해진다 (즉, 클래스 브랜치가 HashSet <MyTree> {}를 확장하는
MyTree.Branches

8
이 접근법 의 주요 문제점은 final클래스 와 함께 사용할 수 없다는 것입니다 .
AJMansfield

14

1.6에서 현재 Java에는 typedef가 없으며 최종 클래스 (Integer, Double 등)를 서브 클래스 할 수 없으므로 원하는 래퍼 클래스를 만드는 것이 가능합니다.


3
참조 된 안티 패턴 기사는 타이핑을 줄이려고한다는 가정을 기반으로합니다 (실제로 유용한 유형 정보를 숨길 수 있음). 대부분의 사람들이 원하는 실제 용도는 유형을 명확하게하고 컴파일러가 자동으로 처리하도록하는 것입니다. 위의 IndexT를 참조하십시오. 공공 송장 fetchInvoiceItem (String, String, String); 공공 송장 대 fetchInvoiceItem (CustomerId, InvoiceId, InvoiceLineItemId); 명시 적 유형과 변환기 / 검증기는 모든 것이 문자열로 시작하는 프로그래밍 웹 API를 훨씬 안전하게 만듭니다.
englebart

자바에서 연산자 oveloading이 없으므로 추악 해집니다
mils

9

다른 사람들이 이전에 언급했듯이
Java에는 typedef 메커니즘이 없습니다.
나는 또한 일반적으로 "가짜 클래스"를 지원하지 않지만 여기에 일반적인 엄격한 규칙이 없어야합니다
.

Map<String, List<Integer>> 

그 목적을 위해 서브 클래스를 갖는 것을 반드시 고려해야합니다.
고려할 수있는 또 다른 접근법은 예를 들어 코드에서 다음과 같은 감속을 갖는 것입니다.

//@Alias Map<String, List<Integer>>  NameToNumbers;

그런 다음 코드에서 NameToNumbers를 사용하고 관련 Java 코드를 처리하고 생성하기위한 사전 컴파일러 태스크 (ANT / Gradle / Maven)가 있어야합니다.
나는이 답변의 독자들에게 이것이 이상하게 들릴지 모른다는 것을 알고 있지만, 이것은 JDK 5 이전에 "어노테이션"을 구현 한 프레임 워크의 수입니다. 이것은 lombok 프로젝트 가 수행하는 작업과 다른 프레임 워크입니다.


5

실제로 Javaland로 전달되는 typedef의 유일한 사용은 앨리어싱 즉, 같은 클래스에 여러 이름을 부여하는 것입니다. 즉, 클래스 "A"가 있고 "B"가 같은 것을 참조하기를 원합니다. C ++에서는 "typedef BA;"를 수행하게됩니다.

불행히도, 그들은 그것을 지원하지 않습니다. 그러나 관련된 모든 유형을 제어하면 라이브러리 수준에서 불쾌한 해킹을 당길 수 있습니다 .B를 A에서 확장하거나 B가 A를 구현하도록하십시오.


14
있는 것은 typedef또한 일반적인 유형의 호출에 대한 별칭을 만들 도움이 될 것입니다. 예를 들면 다음과 같습니다. typedef A<Long,String> B;(이것은 당신이 묘사 한 특별한 경우 일 수 있지만 아이디어의 매력을 조금 더 명확하게 보여줍니다).
igorrs

유스 케이스에서는 기본 유형에 별명을 지정하고 싶습니다. real_tdoubleboolboolean.
Aaron Franke

3

아마도 이것은 또 다른 가능한 교체 일 수 있습니다.

@Data
public class MyMap {
    @Delegate //lombok
    private HashMap<String, String> value;
}

2
myMap유형의 인스턴스 를 정의 할 때 MyMap마다을 myMapInstance.value.SomeOperation()대신 입력하여 실제 HashMap에서만 조작 할 수 있기 때문에 이제 이것이 문제가된다고 생각하지 않습니다 myMapInstance.SomeOperation(). 짜증나 지 않습니까?
mercury0114

2
당신은 여전히 ​​myMapInstance.SomeOperation ()을 할 수 있습니다 – 이것은 @Delegate를위한 것입니다
shrewquest

3

다른 답변에서 언급했듯이 의사 타입 정의 반 패턴을 피해야합니다 . 그러나 typedef는이를 달성 할 수없는 방법이더라도 여전히 유용합니다. 동일한 Java 표현을 가진 다른 추상 유형을 구별하려고합니다. 암호 인 문자열과 주소를 나타내는 문자열 또는 오프셋을 나타내는 정수를 절대 값을 나타내는 문자열과 혼합하지 않으려 고합니다.

검사 프레임 워크는 이전 버전과 호환 방법으로 형식 정의를 정의 할 수 있습니다. 나는 같은 기본 클래스와 같은 int최종 클래스 에서도 작동합니다 String. 런타임 오버 헤드가 없으며 평등 테스트를 중단하지 않습니다.

타입 별칭과 형식 정의 검사기 프레임 워크 설명서는 필요에 따라 형식 정의를 만들 수있는 몇 가지 방법을 설명합니다.




-6

Enum을 사용할 수는 있지만 제한된 값 세트 만 허용한다는 점에서 의미 정의는 typedef와 약간 다릅니다. 또 다른 가능한 해결책은 명명 된 래퍼 클래스입니다. 예 :

public class Apple {
      public Apple(Integer i){this.i=i; }
}

그러나 클래스가 별명으로 다른 기능을 가지고 있지 않다는 것이 코드에서 명확하지 않다는 것을 감안할 때 더 어색한 것처럼 보입니다.


-7

Typedef를 사용하면 항목을 암시 적으로 유형이 아닌 유형에 할당 할 수 있습니다. 어떤 사람들은 확장 기능으로이 문제를 해결하려고합니다. 이것이 왜 나쁜 생각인지에 대한 설명은 여기 IBM에서 읽으십시오.

편집 : 강력한 유형 유추가 유용한 것이지만 typedef관리 언어로 추악한 머리를 키우는 것을 보지 않을 것이라고 생각 합니다.

편집 2 : C #에서는 소스 파일 맨 위에 이와 같은 using 문을 사용할 수 있습니다. 사용되므로 표시된 두 번째 항목을 수행 할 필요가 없습니다. 이름이 변경되는 유일한 시점은 스코프가 두 유형간에 이름 충돌을 일으키는 경우입니다. 이름 변경은 하나의 파일로 제한되며, 파일을 사용한 모든 변수 / 매개 변수 유형은 전체 이름으로 알려져 있습니다.

using Path = System.IO.Path;
using System.IO;

23
"Typedef를 사용하면 항목을 암시 적으로 유형이 아닌 유형에 할당 할 수 있습니다." Typedef를 사용하면 유형의 별명으로 다른 이름을 작성할 수 있습니다. 유형은 여전히 ​​똑같습니다. 짧은 이름을 얻습니다. 형식 유추와는 아무런 관련이 없습니다. -1
jalf

@jalf : 사실, 타입 추론은 정확히 당신이 말하는 것에 대한 해결책으로 사용되지만, "typedef"를 사용하여 이름 충돌을 피할 수있는 또 다른 예를 들었습니다.
Sam Harwell


@AlexanderMalakhov 감사, 내가 나서서 귀하의 링크와 답을 갱신
데이브 맥클 랜드에게

-14

Java에서는 typedef가 필요하지 않습니다. 프리미티브를 제외한 모든 것이 객체입니다. 포인터는없고 참조 만 있습니다. 일반적으로 typedef를 사용하는 시나리오는 대신 객체를 만드는 인스턴스입니다.


19
아니요, 유형의 짧은 이름을 원할 경우 typedef가 여전히 필요합니다. 또는 소스 코드에서 한 위치를 변경하여 한 유형의 사용을 다른 유형으로 대체하려는 경우.
jalf

28
@Bill K : meh, std :: map <int, std :: map <std :: string, boost :: shared_ptr <std :: string>>> :: const_iterator와 같은 것을 입력 한 후 몇 번. 이 경우 이름 단축 typedef는 가독성을 높이고 방해하지 않습니다.
Joel

22
유형의 이름을 바꾸면 가독성이 크게 향상 될 수 있습니다. 무엇을 읽고 이해하기 쉽고 (따라서 더 읽기 쉽습니다) UnmodifiableDirectedGraph<IncrediblyFancyEdgeType, IncrediblyFancyAbstractNode.EvenFancierConcreteNode>또는 IncrediblyFancyGraph? 나는 항상 정의를 참조하여 실제로 무엇이 무엇인지 알아낼 수 있습니다. 그렇게하면 나는 UnmodifiableDirectedGraph<IncrediblyFancyEdge,IncredilyFancyAbstractNode.SlightlyLessFancyConcreteNode>지루함을 놓치지 않을 것입니다.
Aleksandar Dimitrov

10
@AleksandarDimitrov 나는 이것을 입력 할 때 귀하의 의견이 거의 3 세라는 것을 알고 있지만 그 예가 얼마나 설득력 있고 비현실적인지 지적하는 것이 매우 중요하다고 생각합니다 Enterprise. 클래스 이름에는 단어가 포함되어 있지 않습니다 .
Casey

4
나쁜 이름은 가독성을 방해합니다. 좋은 이름이 도움이됩니다. 전체 이름이 너무 길면 코드 형식을 읽기 어렵거나 조이기 어려운 경우 Typedef가 도움이 될 수 있습니다. 또한 다른 사람이 잘못 선택했거나 모호한 클래스 이름과 상호 작용할 때 도움이됩니다. typedef가 본질적으로 코드를 읽을 수 없게 만든다고 생각한다면 import 문을 사용해서는 안되며 항상 정규화 된 클래스 이름을 참조해야한다고 생각해야합니다.
Christopher Barber
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.