Java에서 C # 'var'키워드에 해당하는 것은 무엇입니까?
중 하나 개를 사용 var에 C #의 키워드는 암시 적 형식 선언이다. var에 대한 Java 등가 구문은 무엇입니까 ?
없습니다. 아아, 당신은 전체 유형 이름을 입력해야합니다.
편집 : 게시 7 년 후, 로컬 변수에 대한 유형 유추 (와 var
)가 Java 10에 추가되었습니다.
편집 : 게시 후 6 년 동안 아래에서 의견을 수집하십시오.
C #에
var
키워드가있는 이유는 .NET에 이름이없는 Type을 가질 수 있기 때문입니다. 예 :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;
프로젝트에 Lombok을 추가하면 해당 val 키워드를 사용할 수 있습니다 .
http://projectlombok.org/features/val.html
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는 여전히 정적 타이핑에 전념하고 있습니다!
- 로컬 변수 선언 에서만 사용할 수 있습니다
로컬 시스템에 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'이라는 클래스를 추가했기 때문에 다른 것을 입력 할 필요가 없습니다.
코드는 여전히 장황하지만 적어도 입력 할 필요는 없습니다!
JetBrains에서 Kotlin 을 살펴볼 수는 있지만 Val입니다. var가 아닙니다.
Java 10은 로컬 변수 유형 유추를 얻었으므로 이제는 var
C #과 거의 동일합니다 (알고있는 한).
또한 선언 할 수없는 유형을 유추 할 수 있습니다 (프로그래머가 해당 위치에서 이름을 지정할 수없는 유형 이지만 다른 유형을 나타낼 수는 없지만 Java에는 C # 익명 유형과 같은 유형이 없습니다).
내가 찾을 수있는 한 가지 차이점은 C #에서
var라는 유형이 범위 내에 있으면 var 키워드는 해당 유형 이름으로 확인되며 암시 적으로 유형이 지정된 로컬 변수 선언의 일부로 처리되지 않습니다.
Java 10에서는 var
유효한 유형 이름이 아닙니다.
나는 이것이 더 오래되었다는 것을 알고 있지만 var 클래스를 만들고 다른 유형의 생성자를 만들고 왜 어떤 생성자가 호출되는지에 따라 다른 유형의 var를 얻습니다. 한 유형을 다른 유형으로 변환하는 메소드를 빌드 할 수도 있습니다.
Lombok
var를 지원 하지만 여전히 실험으로 분류됩니다.
import lombok.experimental.var;
var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);
에서 사용할 때 피해야 할 함정은 다음과 같습니다IntelliJ IDEA
. 자동 완성 및 모든 것을 포함하여 예상대로 작동하는 것으로 보입니다. "해킹되지 않은"솔루션이있을 때까지 (예 : JEP 286 : Local-Variable Type Inference )이 방법이 가장 좋습니다.
참고 val
로 지원입니다 Lombok
수정 또는를 만들지 않고뿐만 아니라 lombok.config
.
자바 (10)로, 동등한은 ... var
.
Java 10에서는 로컬 변수에 대해서만 가능합니다 .
넌 할 수있어
var anum = 10; var aString = "Var";
그러나 할 수 없습니다
var anull = null; // Since the type can't be inferred in this case
자세한 내용 은 사양 을 확인하십시오 .
일반적으로 모든 유형에 Object 클래스를 사용할 수 있지만 나중에 유형 캐스팅을 수행했습니다!
예 :-
Object object = 12;
Object object1 = "Aditya";
Object object2 = 12.12;
System.out.println(Integer.parseInt(object.toString()) + 2);
System.out.println(object1.toString() + " Kumar");
System.out.println(Double.parseDouble(object2.toString()) + 2.12);
이 기능은 이제 Java SE 10에서 사용할 수 있습니다. 정적 타입 안전 var는 마침내이를 Java 세계로 만들었습니다. :)
출처 : https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
'Programing' 카테고리의 다른 글
JSF가 게터를 여러 번 호출하는 이유 (0) | 2020.04.04 |
---|---|
예외를 던질 때 어느 부분이 비쌉니까? (0) | 2020.04.04 |
AngularJS URL에서 조각 식별자 제거 (# 기호) (0) | 2020.04.04 |
Ajax를 사용하여 Django 폼셋에 폼을 동적으로 추가 (0) | 2020.04.04 |
전역 플래그가있는 RegExp가 왜 잘못된 결과를 제공합니까? (0) | 2020.04.04 |