Programing

Java에서 C # 'var'키워드에 해당하는 것은 무엇입니까?

lottogame 2020. 4. 4. 10:11
반응형

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. variables는 여전히 100 % 정적으로 입력됩니다. 이것은 컴파일되지 않습니다 :

    var myString = "foo";
    myString = 3;
    
  • var컨텍스트에서 유형이 분명한 경우에도 유용합니다. 예를 들면 다음과 같습니다.

    var currentUser = User.GetCurrent();
    

    내가 책임지고있는 코드 currentUser에는 User클래스 있거나 파생 클래스가 있다고 말할 수 있습니다. 분명히, 당신의 구현이 User.GetCurrentint 반환 한다면 , 이것은 당신에게 해를 끼칠 것입니다.

  • 이것은와 관련이 없지만 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 용 플러그인을 만들어서 varJava로 제공합니다 . 그것은 해킹이므로 일반적인 면책 조항이 적용되지만 Java 개발에 IntelliJ를 사용하고 시도 하려면 https://bitbucket.org/balpha/varsity에 있습니다.


3 월 20 일에 JDK 10이 릴리스되면서 Java varJEP 286에 지정된대로 키워드가 아닌 예약 된 유형 이름을 포함합니다 . 로컬 변수의 경우 이제 다음이 Java 10 이상에서 유효합니다.

var map = new HashMap<String, Integer>();

var자바에서 예약 유형 이름은 거의 동일 var모두 암시 타이핑 (중요한 차이점은 아래 참조) 할 수 있다는에서 C #의 키워드. varJava에서는 JEP 286 : Goals에 열거 된대로 다음 컨텍스트에서 암시 적 유형 유추에만 사용할 수 있습니다 .

  • 이니셜 라이저가있는 지역 변수
  • 향상된 for 루프의 인덱스
  • 전통적인 for-loop로 선언 된 지역 주민

따라서 필드, 리턴 유형, 클래스 이름 또는 인터페이스 이름에는 사용할 var 수 없습니다 . JEP 286 (Brian Goetz 작성)에 명시된 바와 같이 로컬 변수를 선언하고 정의 할 때 긴 유형 이름을 포함 할 필요가 없습니다 .

개발자는 Java 코드 작성과 관련된 의식을 줄이고 정적 유형 안전에 대한 Java의 약속을 유지하면서 개발자가 불필요하게 로컬 변수 유형의 매니페스트 선언을 제거 할 수 있도록하여 개발자 경험을 개선하고자합니다.

var 자바 범위

주목해야한다 var자바의 키워드가 아니라 예약 유형 이름이 아닙니다. JEP 286에서 인용 한 바와 같이 :

식별자 var는 키워드가 아닙니다. 대신 예약 된 유형 이름입니다. 이는 var를 변수, 메소드 또는 패키지 이름으로 사용하는 코드는 영향을받지 않습니다. var를 클래스 또는 인터페이스 이름으로 사용하는 코드는 영향을받습니다 (그러나 이러한 이름은 일반적인 명명 규칙을 위반하기 때문에 실제로는 드 rare니다).

이후 있습니다 var예약 유형 이름이 아닌 키워드입니다, 그것은 여전히 (새로운 유형의 간섭 역할과 함께) 패키지 이름, 메소드 이름, 변수 이름을 사용할 수 있습니다. 예를 들어, 다음은 varJava에서 의 올바른 사용 예입니다 .

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 형식 또는 기타 변수 선언에는 사용할 수 없습니다.

varJava와 C #의 차이점

이것은 varC #과 Java의 차이점 중 하나 입니다. C # var에서는 유형 이름으로 사용할 수 있지만 Java에서는 클래스 이름이나 인터페이스 이름으로 사용할 수 없습니다. C # 설명서 에 따르면 (암시 적으로 형식화 된 지역 변수) :

명명 된 유형 var이 범위 내에 있으면 var키워드는 해당 유형 이름으로 해석되며 암시 적으로 유형이 지정된 로컬 변수 선언의 일부로 취급되지 않습니다.

varC #에서 유형 이름 으로 사용하는 기능 은 약간의 복잡성을 야기하고 복잡한 해결 규칙을 도입합니다. 이는 varJava var에서 클래스 또는 인터페이스 이름 으로 허용하지 않기 때문에 피할 수 없습니다 . varC #에서 형식 이름 의 복잡성에 대한 자세한 내용은 암시 적으로 형식화 된 변수 선언에 대한 제한 적용을 참조하십시오 . `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();

노트:


로컬 시스템에 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은 로컬 변수 유형 유추를 얻었으므로 이제는 varC #과 거의 동일합니다 (알고있는 한).

또한 선언 할 수없는 유형을 유추 할 수 있습니다 (프로그래머가 해당 위치에서 이름을 지정할 수없는 유형 이지만 다른 유형을 나타낼 수는 없지만 Java에는 C # 익명 유형과 같은 유형이 없습니다).

내가 찾을 수있는 한 가지 차이점은 C #에서

var라는 유형이 범위 내에 있으면 var 키워드는 해당 유형 이름으로 확인되며 암시 적으로 유형이 지정된 로컬 변수 선언의 일부로 처리되지 않습니다.

Java 10에서는 var유효한 유형 이름이 아닙니다.


나는 이것이 더 오래되었다는 것을 알고 있지만 var 클래스를 만들고 다른 유형의 생성자를 만들고 왜 어떤 생성자가 호출되는지에 따라 다른 유형의 var를 얻습니다. 한 유형을 다른 유형으로 변환하는 메소드를 빌드 할 수도 있습니다.


Lombokvar를 지원 하지만 여전히 실험으로 분류됩니다.

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

참고 URL : https://stackoverflow.com/questions/3443858/what-is-the-equivalent-of-the-c-sharp-var-keyword-in-java

반응형