ผู้ประกอบการมากไปใน Java


181

คุณช่วยบอกฉันหน่อยได้ไหมว่ามันเป็นไปได้ที่จะโอเวอร์โหลดโอเปอเรเตอร์ใน Java หรือไม่? หากมีการใช้ที่ใดก็ได้ใน Java คุณสามารถบอกฉันเกี่ยวกับมันได้


คำตอบ:


235

ไม่จาวาไม่รองรับการบรรทุกเกินพิกัดที่ผู้ใช้กำหนด แง่มุมเดียวของ Java ที่มาใกล้กับการโอเวอร์โหลดของตัวดำเนินการ "กำหนดเอง" คือการจัดการกับ + สำหรับสตริงซึ่งอาจส่งผลให้การรวมเวลาคงที่ของค่าคงที่หรือการต่อข้อมูลเวลาดำเนินการโดยใช้ StringBuilder / StringBuffer คุณไม่สามารถกำหนดโอเปอเรเตอร์ของคุณเองซึ่งกระทำในลักษณะเดียวกัน

สำหรับ Java เหมือน (และ JVM-based) ภาษาที่ไม่มากไปประกอบการการสนับสนุนคุณสามารถดูKotlinหรือGroovy หรือคุณอาจพบโชคมีวิธีการแก้ปัญหา Java ปลั๊กอินคอมไพเลอร์


4
คุณกำลังบอกว่าเราไม่สามารถสร้าง wrapper ใน java? เช่น SmallInteger เช่น Integer หรือไม่
huseyin tugrul buyukisik

3
@ tuğrulbüyükışık: มี wrappers สำหรับประเภทดั้งเดิมทั้งหมดที่มีอยู่แล้ว - แต่ถ้าคุณต้องการที่จะสร้างประเภท wrapper ใหม่ของคุณเองคุณจะไม่สามารถทำตัวเหมือนคนอื่น ๆ เพราะพวกเขามีการสนับสนุนเฉพาะในภาษา
Jon Skeet

1
ขอบคุณฉัน googled เกี่ยวกับมันและไม่สามารถหาได้ ฉันอยากรู้ว่าฉันสามารถสร้างตัวแปรที่ซับซ้อนประกอบด้วยสองแบบดั้งเดิม (double และ int ---> ความแม่นยำที่ดี + ช่วงที่ดี) หรือไม่
Huseyin tugrul buyukisik

40
@djaqeel: Operator มากไปทำให้โค้ดอ่านได้น้อยลงเมื่อใช้ไม่ดี เมื่อใช้อย่างดีจะช่วยเพิ่มความสามารถในการอ่านได้อย่างมาก ดูโค้ดที่ใช้BigIntegerใน Java จากนั้นดูโค้ดที่คล้ายกันโดยใช้BigIntegerใน C # using โอเปอเรเตอร์ ฉันไม่เห็นว่าผู้เข้าร่วมประชุมทำผิดหลักการของ OOP อย่างไรคุณต้องแม่นยำกว่าในการคัดค้านของคุณ ฉันไม่ทราบรายละเอียดว่าทำไมนักออกแบบ Java จึงไม่ได้รวมคุณสมบัติต่าง ๆ ไว้ แต่ฉันคิดว่ามีส่วนผสมของความกดดันด้านทรัพยากรและความปรารถนาที่จะรักษาภาษาให้เล็กและเรียบง่าย
Jon Skeet

4
ฉันรู้ว่ามันมาสาย แต่ตัวอย่างมีค่ากว่าหนึ่งพันข้อโต้แย้ง ได้รับm0เป็นMatrixและv0, v1, v2, v3และv4เป็นVectors เพียงแค่เปรียบเทียบว่าจะใช้เวลานานให้คุณได้อย่างถูกต้องm0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);ตีความแสดงออกทางคณิตศาสตร์ต่อไปนี้ m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;การสนับสนุนมีสำหรับผู้ประกอบการบรรทุกเกินพิกัดได้รวมก็อาจได้รับการเขียนเป็น
code_dredd

38

ตัวดำเนินการโอเวอร์โหลดถูกใช้ใน Java สำหรับการต่อข้อมูลประเภท String:

String concat = "one" + "two";

อย่างไรก็ตามคุณไม่สามารถกำหนดโอเปอเรเตอร์ของคุณเองได้


26

นอกจากนี้ทุกคนชี้ให้เห็นว่า+มีมากเกินไปสตริง-ยังมากเกินไปสำหรับทั้งจุดลอยและจำนวนเต็มการดำเนินงานเช่นเดียวกับและ*/

[แก้ไข] %มีการโหลดมากเกินไปสำหรับจุดลอยซึ่งอาจเป็นเรื่องน่าประหลาดใจสำหรับผู้ที่มีพื้นหลัง C หรือ C ++


21

Java ไม่อนุญาตให้มีการบรรทุกเกินพิกัด วิธีที่แนะนำคือการกำหนดวิธีการในชั้นเรียนของคุณในการดำเนินการนี้แทนa.add(b) a + bคุณสามารถดูข้อมูลสรุปของบิตอื่น ๆ Java ที่เหลือจาก C เช่นภาษาที่นี่: คุณลักษณะถูกลบออกจาก C และ C ++


2
สิ่งสำคัญคือเป้าหมายการออกแบบในการทำให้บริบทซอร์สไฟล์ Java เป็นอิสระ การพยายามอ่านใหญ่มาก (MLOC) โปรแกรมมาโครเฮฟวี่ซีมีช่วงการเรียนรู้ที่ยาวมาก โปรแกรม Java ที่เปรียบเทียบกัน (หรือใหญ่กว่า) นั้นไม่ยากเกินกว่าโปรแกรม Java ขนาดเล็ก ดังที่ Gosling กล่าวว่า: ภาษาสำหรับโปรแกรมเมอร์ปกสีน้ำเงินทำงาน [และใครก็ตามที่คิดว่าการใช้คำ
ฟุ่มเฟือยในหม้อน้ำ

2
ขอบคุณ oracle ทำให้การเชื่อมโยง java.sun.com ไม่ทำงาน คุณช่วยบอกลิงค์ที่อัพเดทได้ไหมถ้าเป็นไปได้?
Syed Aqeel Ashiq

17

คุณไม่สามารถทำสิ่งนี้ได้ด้วยตนเองเนื่องจาก Java ไม่อนุญาตให้ผู้ให้บริการโหลดมากเกินไป

ด้วยข้อยกเว้นหนึ่งอย่างไรก็ตาม +และ+ =มีการโอเวอร์โหลดสำหรับวัตถุสตริง


8
มีตัวอย่างอื่น ๆ ของโอเปอร์เรเตอร์การโอเวอร์โหลดใน Java ตัวอย่างเช่น&, |และ^โอเวอร์โหลดสำหรับbooleanและประเภทอินทิกรัล และที่จริงแล้วตัวดำเนินการเกี่ยวกับคณิตศาสตร์และเชิงสัมพันธ์นั้นมีจำนวนมากเกินไปสำหรับประเภทตัวเลขต่างๆ (แน่นอนว่าความหมายของการโอเวอร์โหลดนั้นใกล้เคียงกันมาก ... )
สตีเฟนซี

16

ตามที่คนอื่น ๆ ตอบ: Java ไม่รองรับการบรรทุกเกินพิกัดที่ผู้ใช้กำหนด

อาจจะเป็นนอกหัวข้อ แต่ฉันต้องการแสดงความคิดเห็นในสิ่งที่ฉันอ่านในคำตอบบางอย่าง

เกี่ยวกับการอ่าน
เปรียบเทียบ:

  1. c = a + b
  2. c = a.add (b)

ดูอีกครั้ง!
อันไหนที่อ่านได้มากกว่า?

ภาษาการเขียนโปรแกรมที่อนุญาตให้สร้างประเภทที่ผู้ใช้กำหนดควรอนุญาตให้พวกเขาดำเนินการในลักษณะเดียวกับประเภทในตัว (หรือประเภทดั้งเดิม)

ดังนั้น Java จึงแบ่งหลักการพื้นฐานของการเขียนโปรแกรมทั่วไป:
เราควรจะสามารถแลกเปลี่ยนออบเจ็กต์ประเภทที่มีอยู่แล้วภายในกับออบเจ็กต์ที่ผู้ใช้กำหนดเอง
(คุณอาจสงสัยว่า: "เขาพูดว่า 'วัตถุในตัว' หรือไม่" ใช่ดูที่นี่ )

เกี่ยวกับการต่อสตริง:

นักคณิตศาสตร์ใช้สัญลักษณ์ + สำหรับการดำเนินการสลับชุด
ดังนั้นเราจึงมั่นใจได้ว่า a + b = b + a
การต่อสตริง (ในภาษาการเขียนโปรแกรมส่วนใหญ่) ไม่เคารพเครื่องหมายทางคณิตศาสตร์ทั่วไปนี้

a := "hello";
b := "world";
c := (a + b = b + a);

หรือใน Java:

String a = "hello";
String b = "world";
boolean c = (a + b).equals(b + a);

พิเศษ:
สังเกตว่าสับสนในความเท่าเทียมและเอกลักษณ์ของ Java อย่างไร == (ความเสมอภาค) หมายถึงสัญลักษณ์:
ความเท่าเทียมกันสำหรับประเภทดั้งเดิม
ข Identity-check สำหรับประเภทที่ผู้ใช้กำหนดดังนั้นเราถูกบังคับให้ใช้function equals () เพื่อความเท่าเทียมกัน
แต่ ... สิ่งนี้เกี่ยวข้องกับการบรรทุกเกินพิกัดหรือไม่
หากภาษาอนุญาตให้โอเปอเรเตอร์บรรทุกเกินพิกัดผู้ใช้สามารถให้ความหมายที่เหมาะสมกับโอเปอร์เรเตอร์ที่เท่าเทียมกัน


สัญลักษณ์==นี้ใช้สำหรับความเท่าเทียมกันใน Java เช่นเดียวกับใน C และ C ++ สิ่งนี้ไม่เกี่ยวกับตัวดำเนินการมากไป
Hot Licks

2
ตัวดำเนินการ == ใน Java หมายถึงความเท่าเทียมกันสำหรับประเภทดั้งเดิมเท่านั้น สำหรับประเภทที่ผู้ใช้กำหนดหมายถึง Identity ใน C ++ ความหมายถูกกำหนดโดยผู้ใช้ แต่ควรรักษาซีแมนทิกส์ในตัวความเท่าเทียมกัน String a = "hello"; String b = "hello"; บูลีน c = (a == b);
Fernando Pelliccioni

3
ดังนั้นสิ่งที่คุณพูดในความคิดเห็นแรกของคุณเป็นสิ่งที่ผิด ขวา? กรุณาบอกวิธีการทดสอบความเท่าเทียมกันและตัวตนของผู้ใช้ที่กำหนดในซีคุณถูกต้องความคิดเห็นของฉันเกี่ยวกับความเท่าเทียมคือ OT แต่ฉันชี้แจงว่า (ดู "สิ่งที่พิเศษ") ความจริงที่ว่าฉันไม่ได้สร้างภาษาการเขียนโปรแกรมไม่ได้หมายความว่าฉันไม่สามารถวิจารณ์ภาษาที่มีอยู่ได้ ฉันขอโทษถ้าคุณเคยเห็นการวิจารณ์ว่าเป็นสงครามทางศาสนา
Fernando Pelliccioni

1
การใส่สิ่งยาว ๆ สั้น ๆ : java ดูด
Kolya Ivankov


6

เพียงใช้ Xtend พร้อมกับรหัส Java ของคุณ รองรับ Operator Overloading:

    package com.example;

@SuppressWarnings("all")
public class Test {
  protected int wrapped;

  public Test(final int value) {
    this.wrapped = value;
  }

  public int operator_plus(final Test e2) {
    return (this.wrapped + e2.wrapped);
  }
}

package com.example

class Test2 {

    new() {
        val t1 = new Test(3)
        val t2 = new Test(5)
        val t3 = t1 + t2
    }

}

บนเว็บไซต์อย่างเป็นทางการมีรายการวิธีการใช้งานสำหรับผู้ให้บริการแต่ละราย!


5

หรือคุณสามารถสร้าง Java Groovyและเพียงแค่โอเวอร์โหลดฟังก์ชันเหล่านี้เพื่อให้ได้สิ่งที่คุณต้องการ

//plus() => for the + operator
//multiply() => for the * operator
//leftShift() = for the << operator
// ... and so on ...

class Fish {
    def leftShift(Fish fish) {
        print "You just << (left shifted) some fish "
    }
}


def fish = new Fish()
def fish2 = new Fish()

fish << fish2

ใครไม่อยากเป็น / ใช้งาน groovy? : D

ไม่คุณไม่สามารถใช้ JARs ที่รวบรวมได้ใน Java ด้วยวิธีเดียวกัน มันยังคงเป็นข้อผิดพลาดของคอมไพเลอร์สำหรับ Java


1

ซึ่งแตกต่างจาก C ++, Java ไม่รองรับการบรรทุกเกินพิกัดของผู้ใช้ การโหลดมากเกินไปทำได้ภายใน Java

เราสามารถใช้+(บวก) ตัวอย่างเช่น:

int a = 2 + 4;
string = "hello" + "world";

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

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