중 하나 개를 사용 var에 C #의 키워드는 암시 적 형식 선언이다. var에 대한 Java 등가 구문은 무엇입니까 ?
중 하나 개를 사용 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;
var p = new X(); p.Z()
이 아니므로 SuperX p = new X(); p.Z()
모든 X 및 SuperX와 동일하지는 않습니다 X : SuperX
. 와 정적 유형var
p
항상 X
하지만 항상 상기 첫 번째 예에서는 SuperX
두 번째 예이다. 알아야 할 미묘하지만 중요한 차이점. 그러나 당신의 대답은 매우 정확합니다 :-)
var
코드를 덜 명확하게하지 않습니다. 내 의견으로는 반대입니다. 예를 들어 선언하고 인스턴스화 할 때 같은 행에 유형을 두 번 (또는 심지어 세 번) 쓰는 이유는 무엇입니까 (RadioButton radioButton = new RadioButton();
입니까? var
변수 이름을 지정할 때 유형이 아닌 기능성에 초점을 맞추기 때문에 두 번 생각하는 대신 UserCollection collection = new userRepository.GetUsers();
보다 자연스럽게로 바뀝니다 var users = userRepository.GetUsers();
). var
확실하지 않다고 생각되면 사용하지 않기 때문입니다.
var
는 코드를 명확하게 잘 사용할 수있게하지만 너무 잘못 사용하면 명확하지 않을 수 있습니다. 많은 서식 옵션처럼. 익명의 개체 및 제네릭을 얼마나 많이 사용하는지에 따라 균형이 달라집니다. 둘 중 어느 것도 .NET 1.0에 존재하지 않으므로 C in의 첫 번째 버전에서 가상 키워드로 유용하지 않습니다. 나는 단지 이름을RadioButton
radioButton
버튼이나 버튼이 중요한 유일한 것은 그것이 버튼 이었다는 것의 팩토리 또는 헬퍼 방법의 경우RadioButton
지을 var
것이다.
var
당신 만큼이나 한 번 비판적 이었지만, 나는 내 의견을 바꿨으며, 아마도 다른 의견에 대한 질문만큼 간단 할 수도 있습니다. 익명의 객체와 제네릭을 얼마나 많이 사용하고 있는지에 상관없이;) 타입 선언은 코드 노이즈 일뿐입니다.
var
단순히 컴파일러에게 할당에서 형식을 유추하도록 요청합니다. 그것은 구문 설탕이다. 나는 처음에 회의적이었다. 그러나 나는 그것을 종교적으로 사용했지만 아직 혼란을 야기한 시간에 직면하지 않았다. 인스턴스화 할 때 중복성을 제거하고 참조 할 때 유형을 확인할 필요가 없습니다. JAVA 9와 동등한 JAVA는 없습니다.
프로젝트에 Lombok을 추가하면 해당 val 키워드를 사용할 수 있습니다 .
final
불변 인 것은 아닙니다. 고려final StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
. projectlombok.org/features/experimental/var.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에 열거 된대로 다음 컨텍스트에서 암시 적 유형 유추에만 사용할 수 있습니다 .
따라서 필드, 리턴 유형, 클래스 이름 또는 인터페이스 이름에는 사용할 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 : 범위 선택을 참조하십시오 .
var
필드 또는 리턴 유형에 사용할 수 없다는 점에서 Java와 c #의 차이점이 있습니까? 주목해야하는 이유는 무엇입니까?
var
Java에서는 필드 또는 리턴 유형에 사용할 수 없습니다. 이 제한은 var
상황에 따라 달라 지므로 일부 상황 (로컬 변수)에서만 사용할 수 있고 다른 상황에서는 사용할 수 없으므로 중요합니다. 이것은 반드시 Java와 C #의 차이점 일 필요는 없지만 Java에서 사용할 때 일반적으로 중요한 제한 사항입니다 var
.
var
에서 클래스 이름을 만들어 사용할 수 있는 것처럼 보입니다 . 기술적으로 c #의 경우 "컨텍스트 키워드"이지만 Java에서는 동일한 작업을 수행 할 수 없습니다. 틀 렸으면 말해줘.
var
클래스 이름이나 (일반 어쨌든되지 않습니다) 자바에서 인터페이스 이름으로,하지만 당신은 변수 이름, 메소드 이름 및 패키지 이름을 사용할 수 있습니다. 예를 들어, var var = 1;
유효한 Java 문이지만 클래스를 선언하려고 public class var {}
하면 오류가 발생 as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
합니다. var
Java 의 이론적 근거 와 var
C # 의 차이점 에 대해 자세히 설명하기 위해 위의 답변을 업데이트했습니다 .
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 ==> []
var
)는 동일하지 않습니다. 이 var
예 에서는 list
유형 ArrayList
이 아닌 유형 List
입니다.
간단한 솔루션 (괜찮은 IDE를 사용한다고 가정)은 어디서나 'int'를 입력 한 다음 유형을 설정하도록하는 것입니다.
실제로 'var'이라는 클래스를 추가했기 때문에 다른 것을 입력하지 않아도됩니다.
코드는 여전히 장황하지만 적어도 입력 할 필요는 없습니다!
int
)-뭔가 빠졌습니까? (* : Eclipse를 괜찮은 IDE라고 부르지는 않지만 다른 사람들을 판단 할 수는 없습니다 ...)
Java 10은 로컬 변수 유형 유추를 얻었으므로 이제는 var
C #과 거의 동일합니다 (알고있는 한).
그것은 수도 비 denotable 유형 (프로그래머에 의해 그 자리에서 명명 할 수없는 종류, 비록 추론 된 유형이 아닌 다른 denotable이다). 예를 들어 트릭 과 익명 클래스의 트릭을 참조하십시오 (직장에서 절대 사용해서는 안됩니다)var
.
내가 찾을 수있는 한 가지 차이점은 C #에서
var라는 유형이 범위 내에 있으면 var 키워드는 해당 유형 이름으로 확인되며 암시 적으로 유형이 지정된 로컬 변수 선언의 일부로 처리되지 않습니다.
Java 10에서는 var
유효한 유형 이름이 아닙니다.
자바 (10)로, 동등한은 ... 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
.
Java 10에서는 로컬 변수에 대해서만 가능합니다 .
넌 할 수있어
var anum = 10; var aString = "Var";
그러나 할 수 없습니다
var anull = null; // Since the type can't be inferred in this case
자세한 내용 은 사양 을 확인하십시오 .
var
캡처 유형, 교차 유형 및 익명 클래스 유형을 포함하여 여러 유형의 선언 할 수없는 유형에 사용할 수 있습니다. Java 11부터는 람다 매개 변수에도 적용 할 수 있습니다.
일반적으로 모든 유형에 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);
var
공식적 언어로 단어, 당신의 대답은 지금은 옛날 방식을 참조한다.
이 기능은 이제 Java SE 10에서 사용 가능합니다. 정적 타입 안전 var는 마침내이를 Java 세계로 만들었습니다. :)
출처 : https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(나var
) 당신은 특히 "자바 교체"언어 ;-) 사용하는 경우