คำหลัก C # 'var' ใน Java มีอะไรเทียบเท่า


264

การใช้คำหลักvarใน C # คือการประกาศชนิดโดยนัย ไวยากรณ์เทียบเท่า Java สำหรับvarคืออะไร?


4
val(หรือvar) ถ้าคุณใช้ภาษา "การแทนที่ Java" โดยเฉพาะ ;-)

6
@pst: นั่นจะเป็น Scala เหรอ? หืมใช่มันเป็น
rsenna

สำหรับ IntelliJ ฉันส่งสิ่งนี้เป็นคำขอคุณลักษณะ: youtrack.jetbrains.com/issue/IDEA-102808 IDE สามารถยุบรหัสเพื่อแสดง val หรือ var แม้ว่ารหัสพื้นฐานจะไม่มีก็ตาม
Jon Onstott

@ จอนฉันได้ hacked บางสิ่งบางอย่างร่วมกันเพื่อ IntelliJ ดูของฉันคำตอบ
balpha

3
ขณะนี้มีข้อเสนอสำหรับคุณลักษณะนี้ที่จะรวมอยู่ใน Java - openjdk.java.net/jeps/286
McGin

คำตอบ:


248

ไม่มีเลย อนิจจาคุณต้องพิมพ์ชื่อเต็ม

แก้ไข: 7 ปีหลังจากการโพสต์, การอนุมานประเภทสำหรับตัวแปรท้องถิ่น (กับvar) ถูกเพิ่มใน Java 10

แก้ไข: 6 ปีหลังจากโพสต์, เพื่อรวบรวมความคิดเห็นจากด้านล่าง:

  • เหตุผล C # มีvarคำหลักเนื่องจากเป็นไปได้ที่จะมีประเภทที่ไม่มีชื่อใน. NET เช่น:

    var myData = new { a = 1, b = "2" };

    myDataในกรณีนี้มันจะเป็นไปไม่ได้ที่จะให้ชนิดที่เหมาะสมในการ 6 ปีที่แล้วสิ่งนี้เป็นไปไม่ได้ใน Java (ทุกประเภทมีชื่อแม้ว่าพวกเขาจะ verbose อย่างมากและไม่สวย) ฉันไม่ทราบว่าสิ่งนี้มีการเปลี่ยนแปลงในเวลาเฉลี่ย

  • vardynamicไม่ได้เป็นเช่นเดียวกับ variables ยังคงพิมพ์แบบคงที่ 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;

11
@Mike Caron: C # มี [ค่าเริ่มต้น] การโทรที่ไม่ใช่เสมือนจริงและตัวดำเนินการไม่ใช่เสมือนดังนั้น ... var p = new X(); p.Z()ไม่เหมือนกับSuperX p = new X(); p.Z()X และและ SuperX X : SuperXทั้งหมด ด้วยคงที่ประเภทของการอยู่เสมอในตัวอย่างแรกข้างต้น แต่เสมอในตัวอย่างที่สอง ความแตกต่างที่ลึกซึ้ง แต่สำคัญที่ต้องระวัง แต่คำตอบของคุณถูกต้องมาก :-)varpXSuperX

200
@ จอนฮันนา: varไม่ทำให้รหัสชัดเจนน้อยลง ค่อนข้างตรงกันข้ามในความคิดของฉัน ทำไมตัวอย่างเช่นเขียนประเภทสอง (หรือสามครั้ง) ในแถวเดียวกันเมื่อคุณประกาศและยกตัวอย่าง ( RadioButton radioButton = new RadioButton();) varทำให้คุณค่อนข้างคิดว่าสองครั้งเมื่อคุณตั้งชื่อตัวแปรของคุณเพราะมันจะมุ่งเน้นไปที่การทำงานมากกว่าประเภท (เช่น UserCollection collection = new userRepository.GetUsers();ค่อนข้างจะกลายเป็นธรรมชาติมากกว่าvar users = userRepository.GetUsers();) หากคุณคิดว่าvarไม่ชัดเจนอาจเป็นเพราะไม่ได้ใช้งาน
Martin Odhelius

4
@MartinOdhelius varแน่นอนมากสามารถทำให้การใช้รหัสชัดเจนดี แต่ก็สามารถทำให้มันชัดเจนเกินไปใช้ไม่ดี; ชอบตัวเลือกการจัดรูปแบบมากมาย ยอดคงเหลือแตกต่างกันไปขึ้นอยู่กับว่าคุณใช้วัตถุและข้อมูลทั่วไปโดยไม่ระบุชื่อซึ่งไม่มีอยู่ใน. NET 1.0 ทำให้มีประโยชน์น้อยกว่าในฐานะคำหลักสมมุติในรุ่นแรกของC♯ ฉันเพียงจะชื่อRadioButton radioButtonในกรณีของโรงงานหรือผู้ช่วยวิธีการที่มีเพียงสิ่งเดียวที่สำคัญเกี่ยวกับปุ่มก็คือว่ามันเป็นอย่างอื่นที่บ้าของมีหรือไม่มีRadioButton var
Jon Hanna

6
@ จอนฮันนา: ครั้งหนึ่งฉันเคยมีความสำคัญกับvarคุณถ้าไม่มาก แต่ฉันได้เปลี่ยนความคิดเห็นของฉันและบางทีมันอาจจะง่ายเหมือนคำถามของความคิดเห็นที่แตกต่างกันเพราะฉันยังคิดว่าคุณผิดเมื่อคุณพูดว่ามันเป็น ไม่ว่าคุณจะใช้วัตถุและชื่อสามัญมากน้อยเพียงใด) การประกาศประเภทมักจะเป็นเพียงแค่รหัสเสียงถ้าคุณไม่สามารถเข้าใจรหัสได้หากไม่มีรหัสก็อาจไม่ชัดเจนในทั้งสองกรณี
Martin Odhelius

3
คุณกำลังสับสนvarกับประเภทที่ไม่ระบุชื่อ varตัวมันเองก็ขอให้คอมไพเลอร์สรุปประเภทจากการมอบหมาย; มันเป็นน้ำตาลทราย ตอนแรกฉันไม่เชื่อ แต่ฉันใช้มันอย่างเคร่งศาสนาและยังไม่เคยเจอเวลาที่มันทำให้เกิดความสับสน มันลบความซ้ำซ้อนเมื่อ instantiating และลบความจำเป็นในการตรวจสอบประเภทเมื่อมีการอ้างอิง ไม่มีเทียบเท่า JAVA ณ JAVA 9
Robear

46

หากคุณเพิ่มลอมบอกในโครงการของคุณคุณสามารถใช้คำหลักวาล

http://projectlombok.org/features/val.html


1
@rightfold: วัตถุที่มีการอ้างอิงfinalไม่จำเป็นต้องเปลี่ยนแปลง พิจารณาfinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
แมทเธียสส์เบราน์

1
ตั้งแต่ lombok v1.16.12 ก็มีการสนับสนุนการทดลองvarเช่นกัน projectlombok.org/features/experimental/var.html
Roel Spilker

@MatthiasBraun ตัวอย่างของคุณผิด ในกรณีนี้คลาส StringBuilder เองนั้นไม่เปลี่ยนรูปคุณเพียงแค่เพิ่มค่าสตริงลงในโครงสร้างภายในโดยใช้วิธีการ
Andzej Maciusovic

27

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>


@PeterMortensen ใช่ JEP 286 ได้รับการยอมรับและเผยแพร่ใน JDK 10 (ดู 286 ภายใต้คุณลักษณะที่openjdk.java.net/projects/jdk/10 )
Justin Albano

20

ฉันได้ปรุงปลั๊กอินสำหรับ IntelliJ แล้ว - ในแบบที่ให้คุณกับvarJava มันสับดังนั้นการสละสิทธิ์ตามปกติใช้ แต่ถ้าคุณใช้ IntelliJ สำหรับการพัฒนา Java ของคุณและต้องการที่จะลองมันออกมามันจะอยู่ที่https://bitbucket.org/balpha/varsity


มันจะเป็นการดีถ้ามีแป้นพิมพ์ลัดเพื่อพับ / แฉประกาศประเภทในเครื่องมือแก้ไขปัจจุบัน ปลั๊กอินที่ยอดเยี่ยม
ปุ่มลัด

2
@hotkey สิ่งนี้ใช้การพับโค้ดในตัวของ IntelliJ ดังนั้นคุณสามารถเปิดทุกอย่างด้วย Ctrl-Shift-NumPadPlus เมื่อเคอร์เซอร์อยู่บนบรรทัดที่มีการประกาศตัวแปรแบบพับคุณสามารถ Ctrl-NumPadPlus และ Ctrl-NumPadMinus เพื่อพับ / เปิดการประกาศในวิธีการปัจจุบัน การพับการประกาศทั้งหมดเป็นเรื่องที่น่าอึดอัดใจเล็กน้อยคุณมีทุกอย่างที่พับ (Ctrl-Shift-NumPadMinus) จากนั้นคลี่ทุกอย่างอีกครั้ง (Ctrl-Shift-NumPadPlus)
balpha

18

ด้วยการเปิดตัวของ JDK 10 เมื่อวันที่ 20 มีนาคม, Java ตอนนี้มีvarชื่อประเภทที่สงวนไว้ (ไม่ได้เป็นคำหลักดูด้านล่าง) ตามที่ระบุในJEP 286 สำหรับตัวแปรโลคัลตอนนี้สิ่งต่อไปนี้ใช้ได้ใน Java 10 หรือสูงกว่า:

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

varชื่อประเภทที่สงวนไว้ใน Java เป็นเกือบจะเหมือนกับvarคำหลักใน C # ในการที่ทั้งสองช่วยให้สำหรับการพิมพ์โดยปริยาย (ดูด้านล่างสำหรับความแตกต่างที่สำคัญ) varใน Java สามารถใช้สำหรับการอนุมานประเภทโดยนัยในบริบทต่อไปนี้ (ตามที่ระบุในJEP 286: เป้าหมาย ):

  • ตัวแปรโลคัลพร้อมกับ initializers
  • ดัชนีใน for-loop ที่ได้รับการปรับปรุง
  • ท้องถิ่นประกาศในแบบดั้งเดิมสำหรับวง

ดังนั้นจึงvar ไม่สามารถใช้สำหรับฟิลด์ประเภทส่งคืนชื่อคลาสหรือชื่ออินเทอร์เฟซ เหตุผลของมันคือการลบความจำเป็นในการรวมชื่อชนิดยาวเมื่อประกาศและกำหนดตัวแปรท้องถิ่นตามที่ระบุในJEP 286 (เขียนโดย Brian Goetz):

เราพยายามปรับปรุงประสบการณ์ของนักพัฒนาโดยลดพิธีที่เกี่ยวข้องกับการเขียนโค้ด Java ในขณะที่รักษาความมุ่งมั่นของจาวาในการรักษาความปลอดภัยของสแตติกชนิดต่างๆ

var การกำหนดขอบเขตใน Java

ควรสังเกตว่าvarไม่ใช่คำหลักใน Java แต่เป็นชื่อประเภทที่สงวนไว้ ตามที่ยกมาจาก JEP 286:

var ตัวระบุไม่ใช่คำหลัก แต่เป็นชื่อประเภทที่สงวนไว้ ซึ่งหมายความว่ารหัสที่ใช้ var เป็นตัวแปรวิธีการหรือชื่อแพคเกจจะไม่ได้รับผลกระทบ รหัสที่ใช้ var เป็นคลาสหรือชื่ออินเทอร์เฟซจะได้รับผลกระทบ (แต่ชื่อเหล่านี้หายากในทางปฏิบัติเนื่องจากละเมิดหลักการตั้งชื่อตามปกติ)

โปรดทราบว่าเนื่องจาก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:

การรักษานี้จะถูก จำกัด ให้กับตัวแปรในท้องถิ่นที่มี initializers ดัชนีในการปรับปรุงสำหรับวงและท้องถิ่นที่ประกาศในแบบดั้งเดิมสำหรับวง; มันจะไม่สามารถใช้ได้สำหรับ formals วิธี formals นวกรรมิกชนิดกลับวิธีการเขตข้อมูลจับ formals หรือการประกาศตัวแปรชนิดอื่น ๆ

ความแตกต่างระหว่างvarใน Java & C

นี่คือความแตกต่างที่น่าสังเกตระหว่างvarใน C # และ Java รวมถึงต่อไปนี้: varสามารถใช้เป็นชื่อประเภทใน C # แต่ไม่สามารถใช้เป็นชื่อคลาสหรือชื่ออินเตอร์เฟสใน Java ตามเอกสาร C # (ตัวแปรท้องถิ่นที่พิมพ์โดยนัย) :

หากประเภทที่มีชื่อvarอยู่ในขอบเขตvarคำหลักจะแก้ไขเป็นชื่อประเภทนั้นและจะไม่ถือว่าเป็นส่วนหนึ่งของการประกาศตัวแปรท้องถิ่นที่พิมพ์โดยนัย

ความสามารถในการใช้varเป็นชื่อประเภทใน C # สร้างความซับซ้อนและแนะนำกฎการแก้ปัญหาที่ซับซ้อนซึ่งถูกหลีกเลี่ยงโดยvarใน Java โดยไม่อนุญาตให้varใช้เป็นคลาสหรือชื่ออินเตอร์เฟส สำหรับข้อมูลเกี่ยวกับความซับซ้อนของvarชื่อประเภทใน C #, ดูข้อ จำกัด นำไปใช้โดยปริยายพิมพ์ประกาศตัวแปร สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุผลที่อยู่เบื้องหลังการตัดสินใจกำหนดขอบเขตสำหรับ `var ใน Java ดูJEP 286: กำหนดขอบเขตทางเลือก


มีความแตกต่างระหว่าง Java และ c # หรือไม่ที่คุณไม่สามารถใช้varสำหรับฟิลด์หรือชนิดส่งคืนได้? เหตุใดจึงสำคัญที่ควรทราบ
user1306322

@ user1306322 ในบริบทนั้นไม่ varใน Java ไม่สามารถใช้สำหรับฟิลด์หรือประเภทส่งคืน สิ่งนี้มีความสำคัญเนื่องจากข้อ จำกัด นี้ทำให้varบริบทอ่อนไหวซึ่งสามารถใช้ได้ในบริบทบางอย่างเท่านั้น (ตัวแปรท้องถิ่น) และอื่น ๆ สิ่งนี้ไม่จำเป็นต้องเป็นข้อแตกต่างระหว่าง Java และ C # ที่ควรจดบันทึก แต่ข้อ จำกัด ที่สำคัญโดยทั่วไปเมื่อใช้varใน Java
Justin Albano

ฉันเพิ่งค้นหาและดูเหมือนว่าใน c # คุณสามารถสร้างvarชื่อชั้นเรียนและใช้เป็นเช่นนี้ ในทางเทคนิคแล้วมันเป็น "คำหลักบริบท" ในกรณีของ c # แต่ใน Java ดูเหมือนว่าคุณไม่สามารถทำเช่นเดียวกัน ช่วยแก้ให้ด้วยนะถ้าฉันผิด.
user1306322

1
คุณถูก. คุณไม่สามารถใช้varเป็นชื่อคลาสหรือชื่ออินเทอร์เฟซใน Java (ซึ่งไม่ใช่เรื่องธรรมดาอยู่แล้ว) แต่คุณสามารถใช้เป็นชื่อตัวแปรชื่อเมธอดและชื่อแพ็คเกจได้ ยกตัวอย่างเช่น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 #
Justin Albano

11

มันจะได้รับการสนับสนุนใน JDK 10 มันยังเป็นไปได้ที่จะเห็นมันในการดำเนินการในการสร้างการเข้าถึงก่อน

JEP 286 :

เพิ่มประสิทธิภาพภาษา Java เพื่อขยายการอนุมานประเภทเพื่อประกาศตัวแปรท้องถิ่นด้วย initializers

ดังนั้นตอนนี้แทนที่จะเขียน:

List<> list = new ArrayList<String>();
Stream<> stream = myStream();

ที่คุณเขียน:

var list = new ArrayList<String>();
var stream = myStream();

หมายเหตุ:


หากคุณต้องการทดลองใช้งานโดยไม่ต้องติดตั้ง Java ในระบบท้องถิ่นของคุณฉันสร้างอิมเมจ Docker ที่มี JDK 10 ติดตั้งไว้:

$ 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 ==> []

3
ระวังรหัสที่คุณให้ไว้ (ก่อน / หลังvar) จะไม่เทียบเท่า ในvarตัวอย่างlistเป็นประเภทไม่ได้ArrayList List
Gili

8

วิธีแก้ปัญหาอย่างง่าย (สมมติว่าคุณกำลังใช้ IDE ที่เหมาะสม) เพียงพิมพ์ 'int' ทุกที่จากนั้นให้กำหนดประเภทให้คุณ

ฉันเพิ่งเพิ่มคลาสที่เรียกว่า 'var' ดังนั้นฉันจึงไม่ต้องพิมพ์อะไรที่แตกต่างออกไป

รหัสนี้ยังละเอียดเกินไป แต่อย่างน้อยคุณก็ไม่จำเป็นต้องพิมพ์มัน!


เมื่อคุณพูดว่า "เหมาะสม IDE" ไม่รวม Eclipse * - สิ่งนี้ดูเหมือนว่าจะไม่ทำงานใน Luna (อย่างน้อยตอนที่ฉันลองด้วยint) - ฉันขาดอะไรไปหรือเปล่า? (*: ในขณะที่ฉันจะไม่เรียก Eclipse ว่าเป็น IDE ที่ดี แต่ฉันไม่สามารถตัดสินผู้อื่นได้ ... )
BrainSlugs83

@ BrainSlugs83 dunno ฉันใช้ IDEA ไม่เคยใช้ eclipse มาก่อน ไม่ใช่ประเภทที่ถูกต้องสำหรับคุณใช่ไหม ฉันคุ้นเคยกับ c # / visual studio / resharper ซึ่งเหมือนกับ IDEA ยกเว้นว่าใช้งานได้จริง! คุณสามารถกด alt-enter เพื่อดูรายการคำแนะนำเมื่อมีข้อผิดพลาด - ดังนั้นการตั้งค่าประเภทเป็น int จะแนะนำข้อผิดพลาดที่คุณสามารถป้อน alt และนำมาเรียงลำดับ
JonnyRaa

5

คุณสามารถดูKotlinโดย JetBrains แต่มันก็คุ้มค่า ไม่ได้


4
Kotlin มี val และ var. val มีค่าเท่ากับการประกาศตัวแปรสุดท้ายใน java, var อนุญาตให้กำหนดใหม่ได้
samlewis

5

Java 10 ได้รับการอนุมานประเภทตัวแปรท้องถิ่นดังนั้นตอนนี้ก็มีvarซึ่งเทียบเท่ากับ C # หนึ่ง (เท่าที่ฉันรู้)

นอกจากนี้ยังสามารถสรุปประเภทที่ไม่ใช่ denotable (ประเภทที่ไม่สามารถมีชื่ออยู่ในสถานที่ที่โดยโปรแกรมเมอร์แม้ว่าซึ่งประเภทนี้ไม่ denotable ที่แตกต่างกัน) ดูเช่นเทคนิคกับvarและการเรียนที่ไม่ระบุชื่อ (ที่คุณไม่ควรใช้ในที่ทำงาน)

ข้อแตกต่างอย่างหนึ่งที่ฉันพบคือใน C #

หากประเภท var ชื่ออยู่ในขอบเขตแล้วคำหลัก var จะแก้ไขชื่อประเภทนั้นและจะไม่ถือว่าเป็นส่วนหนึ่งของการประกาศตัวแปรท้องถิ่นพิมพ์โดยนัย

ใน Java 10 varไม่ใช่ชื่อประเภทที่ถูกกฎหมาย


@Lii ใช่ฉันจำไม่ได้ว่าฉันหมายถึงอะไรที่นี่ลบออก
Alexey Romanov

ที่ดี! จะลบความคิดเห็นของฉันเพื่อล้างประวัติ!
Lii

4

ในฐานะของ Java ที่ 10 เทียบเท่าคือ var...


มีความแตกต่างหรือไม่? ฉันหมายความว่าคุณรู้ดีกว่าเขียนคำตอบสั้น ๆ แบบนี้สิ่งที่ระดับตัวแทนของคุณทั้งหมด และแน่นอนว่าต้องมีบางอย่างที่แตกต่างกัน
user1306322

@ user1306322 นั่นเป็นคำถามที่แยกจากกันอย่างสิ้นเชิง! คุณอาจตรวจสอบแท็ก java-10 เนื่องจากคำถามนี้ได้ถูกถามมาแล้วหลายแง่มุม
Brian Goetz

ดีนี้เป็นคำถามไปดูที่ถ้าคุณกำลัง googling นี้มันมาก่อนและมีการเชื่อมโยงในทุกโพสต์ที่เกี่ยวข้องในแถบด้านข้าง ดังนั้นฉันคิดว่าถ้าคุณรู้ว่าคำถามแยกต่างหากที่ตอบคำถามคุณอาจเชื่อมโยงกับคำถามนั้นหรือรวมบางส่วนของคำถามลงในคำตอบของคุณ
user1306322

3

ฉันรู้ว่านี่เก่ากว่า แต่ทำไมไม่สร้างคลาส var และสร้าง constructor ที่มีประเภทต่าง ๆ และขึ้นอยู่กับว่า constructor ใดที่ถูกเรียกใช้คุณจะได้รับ var ที่มีประเภทแตกต่างกัน คุณสามารถสร้างวิธีการในการแปลงประเภทหนึ่งเป็นประเภทอื่น


3

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: การอนุมานประเภทตัวแปรท้องถิ่น ) นี่อาจเป็นทางออกที่ดีที่สุดของคุณในตอนนี้

ทราบว่าvalได้รับการสนับสนุนโดยการเป็นอย่างดีโดยไม่ต้องแก้ไขหรือการสร้างLomboklombok.config


2

คุณสามารถใน Java 10 แต่สำหรับตัวแปรLocalหมายถึง

คุณสามารถ,

var anum = 10; var aString = "Var";

แต่ไม่สามารถ

var anull = null; // Since the type can't be inferred in this case

ตรวจสอบข้อมูลจำเพาะสำหรับข้อมูลเพิ่มเติม


2
สิ่งนี้ไม่ถูกต้อง varสามารถใช้สำหรับประเภทที่ไม่สามารถปฏิเสธได้หลายรูปแบบรวมถึงประเภทการจับภาพประเภทการแยกและประเภทคลาสที่ไม่ระบุชื่อ และสำหรับ Java 11 นั้นยังสามารถใช้กับพารามิเตอร์แลมบ์ดาได้
Brian Goetz

0

โดยทั่วไปคุณสามารถใช้คลาส 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);

Aditya โปรดตรวจสอบคำตอบอื่น ๆ ของคุณทั้งหมด หลายคนมี -1 และอาจเป็นเหตุผลที่ดี อย่าเพิ่งโพสต์อะไรหากคุณไม่แน่ใจว่าถูกต้อง
user1306322

@ user1306322 ปัญหาในคำตอบของฉันคืออะไร! คุณสามารถทำอย่างละเอียด? เราไม่สามารถใช้คลาสวัตถุสำหรับประเภทข้อมูลทั้งหมดได้หรือไม่
Aditya Kumar

วัตถุ Object = 12; Object object1 = "Aditya"; วัตถุ 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)
Aditya Kumar

ปัญหาคือคุณไม่เข้าใจคำถาม คำถามไม่ใช่ "วิธีการทำงานนี้" แต่ "มีสิ่งนี้หรือไม่" คุณตอบคำถามที่ผิด ด้วยvarคำที่เป็นทางการในภาษานี้คำตอบของคุณยังหมายถึงวิธีที่ล้าสมัยในขณะนี้
user1306322

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.