[java] Java에서 C # ‘var’키워드에 해당하는 것은 무엇입니까?
중 하나 개를 사용 var에 C #의 키워드는 암시 적 형식 선언이다. var에 대한 Java 등가 구문은 무엇입니까 ?
답변
없습니다. 아아, 당신은 전체 유형 이름을 입력해야합니다.
편집 : 게시 7 년 후, 로컬 변수에 대한 유형 유추 (와 var
)가 Java 10에 추가되었습니다.
편집 : 게시 후 6 년 동안 아래에서 의견을 수집하십시오.
-
C #에
var
키워드가있는 이유는 .NET에 이름이없는 유형을 가질 수 있기 때문입니다. 예 :var myData = new { a = 1, b = "2" };
이 경우에 적절한 유형을 부여하는 것은 불가능합니다
myData
. 6 년 전, Java에서는 불가능했습니다 (모든 유형은 이름이 매우 장황하고 부조 한 경우에도 이름이있었습니다). 그 동안 이것이 변했는지 알 수 없습니다. -
var
와 동일하지 않습니다dynamic
.var
iables는 여전히 100 % 정적으로 입력됩니다. 이것은 컴파일되지 않습니다 :var myString = "foo"; myString = 3;
-
var
컨텍스트에서 유형이 분명한 경우에도 유용합니다. 예를 들면 다음과 같습니다.var currentUser = User.GetCurrent();
내가 책임지고있는 코드 에서 클래스가 파생되었거나 클래스를
currentUser
가지고 있다고 말할 수 있습니다User
. 분명히, 당신의 구현이User.GetCurrent
int 를 반환 한다면 , 이것은 당신에게 해를 끼칠 것입니다. -
이것과는 아무런 관련이
var
없지만 다른 메소드 (예 :)로 메소드를 음영 처리하는 이상한 상속 계층 구조가있는 경우new public void DoAThing()
비가 상 메소드가 유형에 의해 영향을 받는다는 것을 잊지 마십시오.이것이 좋은 디자인을 나타내는 실제 시나리오를 상상할 수는 없지만 예상대로 작동하지 않을 수 있습니다.
class Foo { public void Non() {} public virtual void Virt() {} } class Bar : Foo { public new void Non() {} public override void Virt() {} } class Baz { public static Foo GetFoo() { return new Bar(); } } var foo = Baz.GetFoo(); foo.Non(); // <- Foo.Non, not Bar.Non foo.Virt(); // <- Bar.Virt var bar = (Bar)foo; bar.Non(); // <- Bar.Non, not Foo.Non bar.Virt(); // <- Still Bar.Virt
표시된대로 가상 메소드는 이에 영향을받지 않습니다.
-
아니요,
var
실제 변수없이 초기화하는 비 서투른 방법은 없습니다 .var foo1 = "bar"; //good var foo2; //bad, what type? var foo3 = null; //bad, null doesn't have a type var foo4 = default(var); //what? var foo5 = (object)null; //legal, but go home, you're drunk
이 경우 구식 방식으로 수행하십시오.
object foo6;
답변
답변
JEP-JDK 개선 제안
http://openjdk.java.net/jeps/286
JEP 286 : 로컬 변수 유형 유추
저자 Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
답변
나는 IntelliJ 용 플러그인을 만들어서 var
Java로 제공합니다 . 그것은 해킹이므로 일반적인 면책 조항이 적용되지만 Java 개발에 IntelliJ를 사용하고 시도 하려면 https://bitbucket.org/balpha/varsity에 있습니다.
답변
3 월 20 일에 JDK 10이 릴리스되면서 Java var
에 JEP 286에 지정된대로 키워드가 아닌 예약 된 유형 이름이 포함됩니다 (아래 참조) . 지역 변수의 경우 이제 다음이 Java 10 이상에서 유효합니다.
var map = new HashMap<String, Integer>();
var
자바에서 예약 유형 이름은 거의 동일 var
모두 암시 타이핑 (중요한 차이점은 아래 참조) 할 수 있다는에서 C #의 키워드. var
Java에서는 JEP 286 : Goals에 열거 된대로 다음 컨텍스트에서 암시 적 유형 유추에만 사용할 수 있습니다 .
- 이니셜 라이저가있는 지역 변수
- 향상된 for 루프의 인덱스
- 전통적인 for-loop로 선언 된 지역 주민
따라서 필드, 리턴 유형, 클래스 이름 또는 인터페이스 이름에는 사용할 var
수 없습니다 . JEP 286 (Brian Goetz 작성)에 명시된 바와 같이 로컬 변수를 선언하고 정의 할 때 긴 유형 이름을 포함 할 필요가 없어야합니다.
개발자는 Java 코드 작성과 관련된 의식을 줄이고 정적 유형 안전에 대한 Java의 약속을 유지하면서 개발자가 불필요하게 로컬 변수 유형의 매니페스트 선언을 제거 할 수 있도록하여 개발자 경험을 개선하고자합니다.
var
자바 범위
주목해야한다 var
자바의 키워드가 아니라 예약 유형 이름이 아닙니다. JEP 286에서 인용 한 바와 같이 :
식별자 var는 키워드가 아닙니다. 대신 예약 된 유형 이름입니다. 이는 var를 변수, 메소드 또는 패키지 이름으로 사용하는 코드는 영향을받지 않습니다. var를 클래스 또는 인터페이스 이름으로 사용하는 코드는 영향을받습니다 (그러나 이러한 이름은 일반적인 명명 규칙을 위반하기 때문에 실제로는 드 rare니다).
이후 있습니다 var
예약 유형 이름이 아닌 키워드입니다, 그것은 여전히 (새로운 유형의 간섭 역할과 함께) 패키지 이름, 메소드 이름, 변수 이름을 사용할 수 있습니다. 예를 들어, 다음은 var
Java에서 의 올바른 사용 예입니다 .
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
JEP 286에서 인용 한 바와 같이 :
이 처리는 이니셜 라이저, 향상된 for-loop의 색인 및 전통적인 for-loop에서 선언 된 지역 변수를 사용하는 지역 변수로 제한됩니다. 메소드 형식, 생성자 형식, 메소드 리턴 유형, 필드, catch 형식 또는 기타 변수 선언에는 사용할 수 없습니다.
var
Java와 C의 차이점
이것은 var
C #과 Java의 차이점 중 하나 입니다. C # var
에서는 유형 이름으로 사용할 수 있지만 Java에서는 클래스 이름이나 인터페이스 이름으로 사용할 수 없습니다. C # 설명서 에 따르면 (암시 적으로 형식화 된 지역 변수) :
명명 된 유형
var
이 범위 내에 있으면var
키워드는 해당 유형 이름으로 해석되며 암시 적으로 유형이 지정된 로컬 변수 선언의 일부로 취급되지 않습니다.
var
C #에서 유형 이름 으로 사용하는 기능 은 약간의 복잡성을 야기하고 복잡한 해결 규칙을 도입합니다. 이는 var
Java var
에서 클래스 또는 인터페이스 이름 으로 허용하지 않기 때문에 피할 수 없습니다 . var
C #에서 형식 이름 의 복잡성에 대한 자세한 내용은 암시 적으로 형식화 된 변수 선언에 대한 제한 적용을 참조하십시오 . `var in Java의 범위 결정에 대한 이론적 근거에 대한 자세한 정보는 JEP 286 : 범위 선택을 참조하십시오 .
답변
JDK 10에서 지원 될 것입니다. 초기 액세스 빌드 에서 실제로 작동하는 것을 볼 수도 있습니다. 입니다. .
JEP 286 :
이니셜 라이저를 사용하여 유형 유추를 로컬 변수 선언으로 확장하도록 Java 언어를 향상 시키십시오.
이제 글을 쓰는 대신
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
당신은 쓰기:
var list = new ArrayList<String>();
var stream = myStream();
노트:
var
이제는 예약 된 유형 이름입니다.- 자바는 여전히 정적 타이핑에 전념하고 있습니다!
- 로컬 변수 선언 에서만 사용할 수 있습니다
로컬 시스템에 Java를 설치하지 않고 시도해보고 싶다면 JDK 10이 설치된 Docker 이미지 를 만들었 습니다.
$ docker run -it marounbassam/ubuntu-java10 bash
root@299d86f1c39a:/# jdk-10/bin/jshell
Mar 30, 2018 9:07:07 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 10
| For an introduction type: /help intro
jshell> var list = new ArrayList<String>();
list ==> []
답변
간단한 솔루션 (괜찮은 IDE를 사용한다고 가정)은 어디서나 ‘int’를 입력 한 다음 유형을 설정하도록하는 것입니다.
실제로 ‘var’이라는 클래스를 추가했기 때문에 다른 것을 입력하지 않아도됩니다.
코드는 여전히 장황하지만 적어도 입력 할 필요는 없습니다!