รูปแบบที่ยอมรับสำหรับการใช้คำหลัก `this 'ใน Java คืออะไร


37

ฉันมาจากภาษาต่าง ๆ เช่น Python หรือ Javascript (และอื่น ๆ ที่ไม่ค่อยมีวัตถุประสงค์เชิงวัตถุ) และฉันพยายามปรับปรุงความรู้การทำงานของ Java ซึ่งฉันรู้เพียงแค่ผิวเผินเท่านั้น

มันถือว่าเป็นการปฏิบัติที่ไม่ถูกต้องหรือไม่ที่จะผนวกthisเข้ากับแอ็ตทริบิวต์อินสแตนซ์ปัจจุบันเสมอ? ฉันรู้สึกเป็นธรรมชาติมากขึ้นที่จะเขียน

...
private String foo;

public void printFoo() {
    System.out.println(this.foo);
}
...

กว่า

...
private String foo;

public void printFoo() {
    System.out.println(foo);
}
...

มันช่วยให้ฉันแยกแยะแอตทริบิวต์ของอินสแตนซ์จากตัวแปรโลคอล

แน่นอนในภาษาอย่าง Javascript มันสมเหตุสมผลมากกว่าที่จะใช้เสมอthisเนื่องจากมีหนึ่งฟังก์ชันที่สามารถซ้อนฟังก์ชันได้ดังนั้นตัวแปรท้องถิ่นจึงมาจากขอบเขตที่กว้างขึ้น ใน Java เท่าที่ฉันเข้าใจไม่มีการทำรังแบบนี้เป็นไปได้ (ยกเว้นคลาสภายใน) ดังนั้นอาจไม่ใช่ปัญหาใหญ่

ในกรณีใด ๆ thisฉันชอบที่จะใช้ มันจะรู้สึกแปลกและไม่สำนวนหรือไม่?


เราใช้เครื่องมือเพื่อลดความยุ่งยากใน บริษัท ของเรา เครื่องมือทำซ้ำรหัสด้วยไม่มีของเรานี้ขึ้นอยู่กับนโยบายของ บริษัท ดังนั้นรหัสใครเลยว่าพวกเขาชอบรูปแบบใดและรหัสถูกจัดรูปแบบวิธีการที่เหมาะสมในเวลาที่กระทำ
deadalnix

2
"ตั้งแต่หนึ่งสามารถมีการซ้อนฟังก์ชันได้มากขึ้นดังนั้นตัวแปรท้องถิ่นจึงมาจากขอบเขตที่ใหญ่กว่า" นอกจากนี้ความจริงที่ว่า "นี่" ไม่ใช่ความจริงที่หนึ่งที่ตัวแปรที่ไม่มีเงื่อนไขสามารถมาจากฟังก์ชั่นใน JS
Random832

2
thisฉันคำนำหน้าเช่นตัวแปรทั้งหมดที่มีขีดดังนั้นฉันสามารถบอกความแตกต่างระหว่างตัวแปรท้องถิ่นและอินสแตนซ์โดยไม่ต้องใช้
WuHoUnited

4
ใน C # StyleCop ต้องการให้คุณใส่this.เมื่ออ้างถึงตัวแปรสมาชิกวิธีการ ฯลฯ ฉันชอบที่ฉันเห็นด้วยกับกฎนี้ ฉันคิดว่ามันจะดีกว่าการตั้งชื่อบางอย่างด้วยการขีดเส้นใต้ที่จุดเริ่มต้น ฉันจะปฏิบัติตามกฎเดียวกันหากฉันถูกเข้ารหัสใน java
งาน

คำตอบ:


40

ใน IDEs ส่วนใหญ่คุณสามารถเพียงวางเมาส์ตัวแปรถ้าคุณต้องการที่จะรู้ นอกจากนี้หากคุณกำลังทำงานในวิธีการอินสแตนซ์คุณควรรู้ตัวแปรทั้งหมดที่เกี่ยวข้อง หากคุณมีการปะทะกันมากเกินไปหรือชื่อของพวกเขาแล้วคุณต้อง refactor

มันซ้ำซ้อนจริงๆ


7
นอกจากนี้: IDE ที่มีเหตุผลควรทำให้ฟิลด์และตัวแปร / พารามิเตอร์ในตัวเครื่องแตกต่างกันอย่างเห็นได้ชัด ตัวอย่างเช่นในฟิลด์ Eclipse (โดยค่าเริ่มต้น) เป็นสีน้ำเงินในขณะที่ตัวแปรท้องถิ่นเป็นสีดำ
โจอาคิมซาวเออร์

1
@Joachim จุดที่ดี Eclipse สามารถแม้กระทั่งพารามิเตอร์สีและตัวแปรท้องถิ่นแตกต่างกันไปหากผู้ใช้ต้องการ (นี่ไม่ใช่ค่าเริ่มต้น)
Eric-Karl

3
แม้ว่าฉันจะเห็นด้วยเมื่อเจอรหัสของนักพัฒนาคนอื่น (และในขณะที่ไม่คุ้นเคยในแวบแรก) ฉันพบว่าthis.มีประโยชน์มากขึ้น อาจเป็นเพราะฉันไม่มี IDE ที่ตัวแปรรหัสท้องถิ่น / วัตถุแตกต่างกัน
แบรดคริสตี้

3
+1 สำหรับ (ถอดความ) "refactor หากคุณต้องการใช้สิ่งนี้เพื่ออนุมานว่าเป็นสมาชิก" สิ่งที่ฉันต้องการชี้ให้เห็น
Yam Marcovic

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

26

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

อย่างไรก็ตามมีข้อโต้แย้งเกี่ยวกับเรื่องนี้ ใน IDEs ที่ทันสมัยคุณสามารถค้นหาขอบเขตของตัวแปรได้โดยการวางเมาส์เหนือมันหรือดูมันในโครงสร้างแบบต้นไม้ คุณยังสามารถเปลี่ยนสีและ / หรือแบบอักษรของตัวแปรขึ้นอยู่กับขอบเขตของมัน (แม้ในลักษณะที่เมื่อพิมพ์ออกมามันก็จะเห็นได้ว่าขอบเขตของตัวแปรคืออะไร)

ฉันเชื่อว่าประโยคสุดท้ายของ ChrisFตายไปแล้ว: ให้สอดคล้องกับการใช้งานของคุณ


7
"นอกจากนี้ยังเป็นตัวเตือนที่แข็งแกร่งพอสมควรเกี่ยวกับขอบเขตของตัวแปรสำหรับนักพัฒนาอื่น ๆ " - เหตุผลที่ฉันมักจะใช้และชอบดูthis.ในรหัส ใช้เวลาครึ่งวินาทีในการเขียนและสามารถประหยัดเวลาได้ไม่นานเมื่อต้องคิดออกว่าคนที่แต่งตัวประหลาดก่อนที่คุณจะใช้ทรัพย์สินปาสคาลแทนที่จะใช้อูฐเคสในท้องถิ่นเมื่อเขาทำให้เกิดการเปลี่ยนแปลงในนาทีที่ 20 ที่ผ่านมา
scrwtp

18

ที่เดียวที่ฉันใช้ 'this' อย่างสม่ำเสมอคือ setters และหรือ constructors:

public void setFoo(String foo) {
    this.foo = foo;
}

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

หากมีความสับสนเกี่ยวกับสิ่งที่ตัวแปรและเขตข้อมูลมันอาจหมายถึงวิธีการที่มีตัวแปร / พารามิเตอร์มากเกินไปยาวเกินไปและซับซ้อนเกินไปและควรทำให้ง่ายขึ้น

หากคุณเลือกที่จะใช้แท็ก 'this' เพื่อแท็กฟิลด์ฉันขอแนะนำให้ตรวจสอบให้แน่ใจว่ามีการปฏิบัติตามอนุสัญญาอย่างเคร่งครัด - มันจะง่ายมากที่จะเริ่มสมมติว่าไม่มี "นี่" หมายความว่ามันเป็นของท้องถิ่นและทำลายเนื้อหาตามสมมติฐาน

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

public boolean isSame(MyClass that) {
    return this.uuid().equals(that.uuid());
}

8

มันเป็นที่ถกเถียงกัน

การใช้ C # เป็นการเปรียบเทียบเนื่องจากมีไวยากรณ์และโครงสร้างที่คล้ายกันมากกับ Java เราพบว่า C # StyleCop มีกฎเริ่มต้นที่ยืนยันว่าคุณเพิ่มthisแต่ ReSharper มีกฎเริ่มต้นที่ระบุว่าthisซ้ำซ้อน (ซึ่งเป็น) และสามารถ ลบออก

ดังนั้นหากคุณใช้เครื่องมือหนึ่งคุณจะต้องเพิ่มเครื่องมือ แต่ถ้าคุณใช้เครื่องมืออื่นคุณจะลบเครื่องมือเหล่านั้นออก หากคุณใช้เครื่องมือทั้งสองคุณจะต้องเลือกและปิดใช้งานกฎข้อใดข้อหนึ่ง

อย่างไรก็ตามกฎหมายถึงอะไรคือคุณมีความสอดคล้องในการใช้งานของคุณ - ซึ่งอาจเป็นสิ่งที่สำคัญที่สุด


8

ถือว่าเป็นการปฏิบัติที่ไม่ถูกต้องหรือไม่ที่จะผนวกสิ่งนี้กับแอตทริบิวต์ของอินสแตนซ์ปัจจุบันหรือไม่

ใช่ - โดยบางคนไม่ - โดยคนอื่น

ฉันชอบและใช้thisคำหลักในโครงการของฉันใน Java และ C # เราสามารถยืนยันได้ว่า IDE จะเน้นพารามิเตอร์และเขตข้อมูลด้วยสีที่ต่างกันเสมอ แต่เราไม่ได้ทำงานใน IDE เสมอ - เราต้องทำการผสาน / diffs / การเปลี่ยนแปลงอย่างรวดเร็วใน notepad / ตรวจสอบตัวอย่างโค้ดในอีเมล . เป็นวิธีที่ง่ายกว่าสำหรับฉันที่จะมองจากรูปลักษณ์แรกที่มีการเปลี่ยนแปลงสถานะของอินสแตนซ์ - ตัวอย่างเช่นเพื่อตรวจสอบปัญหาที่เกิดขึ้นพร้อมกันได้


7

ฉันคิดว่าถ้าคุณจำเป็นต้องใช้สิ่งนี้คุณมีวิธีการที่ยาวเกินไปหรือคลาสที่พยายามทำมากเกินไปหรือทั้งสองอย่าง

วิธีการไม่ควรยาวเกินสองสามบรรทัดของโค้ดใช้หนึ่งหรือสองตัวแปรในท้องถิ่นเพื่อกำหนดว่าอะไรจะง่าย แม้จะมีบริบทเพียง 3 บรรทัดของเครื่องมือ diff ส่วนใหญ่ หากวิธีการของคุณยาวเกินไปและชั้นเรียนของคุณมีความรับผิดชอบมากเกินไป (มักจะหมายถึงฟิลด์มากเกินไป) วิธีแก้ไขคือแยกพวกเขาแทน

ฉันคิดว่า "นี่" เป็นเพียงแค่กลุ่มรหัส โดยเฉพาะอย่างยิ่งกับ IDEs สมัยใหม่ที่จะให้สีพารามิเตอร์ท้องถิ่น / ตัวแปร / ท้องที่แตกต่างกัน


5

ฉันคิดว่าคุณตอบคำถามของคุณเองด้วยสิ่งนี้:

ฉันรู้สึกเป็นธรรมชาติมากขึ้นที่จะเขียน

... สิ่งนี้ ...

กว่า

... foo ...

มันช่วยให้ฉันแยกแยะแอตทริบิวต์ของอินสแตนซ์จากตัวแปรโลคอล

หากคุณรู้สึกสะดวกสบายthis.ในการใช้งานมากขึ้นในขณะที่พัฒนาความรู้การทำงานของคุณกับ Java ให้ใช้สิ่งนั้น ( ฉันคิดว่ามันเป็นPython ที่คุ้นเคยที่คุณเกี่ยวข้อง )

ประเด็นก็คือแม้ว่าผู้คนจะให้ข้อโต้แย้งที่เป็นของแข็ง / ตรงประเด็นเกี่ยวกับการใช้หรือไม่ใช้this.ก็ตาม แต่ก็ยังฟังดูเหมือนเป็นการโต้แย้งยกตัวอย่างเช่น:

  • มันทำให้วัตถุประสงค์ของตัวแปรชัดเจนเมื่อเทียบกับคุณควรเขียนโค้ดใหม่หากไม่ชัดเจนว่าแต่ละตัวแปรคืออะไร
  • this.ซ้ำซ้อนหากคุณใช้เวลาทั้งวันใน IDE กับฉันทำการตรวจสอบโค้ดและสร้างความแตกต่างในเวอร์ชันที่ต่างกันโดยใช้ตัวเปรียบเทียบโดยไม่มีการเน้นไวยากรณ์
  • การไม่พิมพ์this.ทำให้ฉันได้รับผลผลิตเป็นมิลลิวินาทีสำคัญเมื่อเทียบกับฉันได้รับthis.การชำระเงินด้วยการกดปุ่มและการเพิ่มก็เหมือนกับการจ่ายเงินเพิ่ม: D;
  • ฯลฯ

แต่บรรทัดล่างคือว่า ณ สิ้นวันก็ยังคงดำเนินการต่อไปตามความต้องการส่วนบุคคลและสภาพแวดล้อมการทำงาน


5

โดยปกติแล้วการเพิ่มสิ่งนี้ไม่จำเป็น ฉันไม่คิดว่ามันเป็นการฝึกฝนที่ไม่ดี แต่การใช้สิ่งนี้มากเกินไปอาจถือว่าผิดปกติในฐานรหัส Java ส่วนใหญ่ที่ฉันเคยเห็น

อย่างไรก็ตามฉันคิดว่ามันมีค่าในบางสถานการณ์:

การเอาชนะพารามิเตอร์โลคัล - บางครั้งจำเป็นต้องระบุว่าคุณต้องการใช้ตัวแปรอินสแตนซ์แทนที่จะเป็นพารามิเตอร์ / ตัวแปรโลคอลที่มีชื่อเดียวกัน นี่เป็นเรื่องปกติในตัวสร้างที่คุณต้องการชื่อพารามิเตอร์ให้ตรงกับชื่อภายในของตัวแปรอินสแตนซ์ที่จะใช้ในการเริ่มต้นเช่น

class MyObject {
  int value;

  public MyObject(int value) {
    this.value=value;
  }
}

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

class MyObject {
  int value;
  ....

  public MyObject add(MyObject other) {
    return new MyObject( this.value + other.value )
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.