Quá tải toán tử trong Java


Câu trả lời:


235

Không, Java không hỗ trợ quá tải toán tử do người dùng định nghĩa. Khía cạnh duy nhất của Java gần với quá tải toán tử "tùy chỉnh" là việc xử lý + cho các chuỗi, dẫn đến kết hợp thời gian biên dịch của các hằng số hoặc nối thời gian thực hiện bằng StringBuilder / StringBuffer. Mặc dù vậy, bạn không thể xác định toán tử riêng của mình hoạt động theo cùng một cách.

Đối với một ngôn ngữ Java như (và JVM-based) mà không điều hành hỗ trợ quá tải, bạn có thể nhìn vào Kotlin hay Groovy . Ngoài ra, bạn có thể tìm thấy may mắn với giải pháp plugin trình biên dịch Java .


4
Bạn đang nói rằng chúng tôi không thể tạo trình bao bọc trong java? Chẳng hạn như SmallInteger như Integer?
huseyin tugrul buyukisik

3
@ tuğrulbüyükışık: Đã có các hàm bao cho tất cả các kiểu nguyên thủy hiện có - nhưng nếu bạn muốn tạo loại trình bao bọc mới của riêng mình, bạn sẽ không thể làm cho nó hoạt động như các loại khác, vì chúng có hỗ trợ cụ thể trong ngôn ngữ.
Jon Skeet

1
cảm ơn, tôi đã tìm hiểu về nó và không thể tìm thấy. Tôi muốn biết liệu tôi có thể tạo ra một biến phức gồm hai nguyên thủy (một nhân đôi và một int ---> độ chính xác tốt + phạm vi tốt)
huseyin tugrul buyukisik

40
@djaqeel: Quá tải toán tử làm cho mã ít đọc hơn khi sử dụng kém . Khi được sử dụng tốt, nó có thể tăng cường khả năng đọc IMO rất nhiều. Nhìn vào mã sử dụng BigIntegertrong Java, sau đó xem mã tương tự bằng BigIntegercách sử dụng toán tử trong C #. Tôi không thấy các đại biểu phá vỡ các nguyên tắc OOP - bạn cần chính xác hơn nhiều so với các phản đối của bạn. Tôi không biết chi tiết lý do tại sao các nhà thiết kế Java không bao gồm các tính năng khác nhau, nhưng tôi nghi ngờ có sự pha trộn giữa áp lực tài nguyên và mong muốn giữ cho ngôn ngữ nhỏ và tương đối đơn giản.
Jon Skeet

4
Tôi biết điều này là muộn, nhưng một ví dụ đáng giá ngàn tranh luận. Với m0như một Matrixv0, v1, v2, v3, và v4như Vectors, chỉ cần so sánh bao lâu nó sẽ đưa bạn đến một cách chính xác giải thích các biểu thức toán học sau m0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);. Đã bao gồm hỗ trợ cho quá tải toán tử, nó có thể được viết là m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;.
code_dredd

38

Quá tải toán tử được sử dụng trong Java để nối chuỗi kiểu:

String concat = "one" + "two";

Tuy nhiên, bạn không thể xác định quá tải toán tử của riêng bạn.


26

Ngoài tất cả những người chỉ ra rằng +bị quá tải cho Chuỗi, -cũng bị quá tải cho cả các phép toán dấu phẩy động và số nguyên, như */.

[sửa] %cũng bị quá tải cho dấu phẩy động, điều này có thể gây bất ngờ cho những người có nền C hoặc C ++.


21

Java không cho phép quá tải toán tử. Cách tiếp cận ưa thích là xác định một phương thức trên lớp của bạn để thực hiện hành động: a.add(b)thay vì a + b. Bạn có thể xem tóm tắt về các bit khác mà Java bỏ qua từ C như các ngôn ngữ ở đây: Các tính năng bị xóa khỏi C và C ++


2
Điều quan trọng là mục tiêu thiết kế làm cho bối cảnh các tệp nguồn Java trở nên độc lập. Cố gắng đọc rất lớn (MLOC), các chương trình C nặng vĩ mô có thời gian học rất dài. Một chương trình Java có thể so sánh (hoặc lớn hơn) không khó nhúng vào hơn một chương trình Java nhỏ. Như Gosling đã nói: Một ngôn ngữ để các lập trình viên cổ xanh làm việc. [Và bất cứ ai nghĩ rằng tính dài dòng của nồi hơi là bất lợi nên đọc về chunk trong nhận thức của chuyên gia.]
Tim Williscroft

2
Nhờ oracle, không có liên kết java.sun.com nào hoạt động. Bạn có thể vui lòng cung cấp các liên kết cập nhật, nếu có thể?
Syed Aqeel Ashiq

17

Bạn không thể tự làm điều này vì Java không cho phép quá tải toán tử.

Tuy nhiên, với một ngoại lệ. ++ = bị quá tải cho các đối tượng String.


8
Có nhiều ví dụ khác về quá tải toán tử trong Java. Ví dụ &, |^là quá tải cho booleancác loại và tích phân. Và thực tế, các toán tử số học và quan hệ bị quá tải cho các loại số khác nhau. (Tất nhiên, ngữ nghĩa của tình trạng quá tải gần hơn nhiều ...)
Stephen C

16

Như nhiều người khác đã trả lời: Java không hỗ trợ quá tải toán tử do người dùng định nghĩa.

Có thể đây là ngoài chủ đề, nhưng tôi muốn bình luận về một số điều tôi đọc trong một số câu trả lời.

Về khả năng đọc.
Đối chiếu:

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

Nhìn lại!
Cái nào dễ đọc hơn?

Một ngôn ngữ lập trình cho phép tạo ra các loại do người dùng xác định, sẽ cho phép chúng hoạt động giống như các loại tích hợp (hoặc các kiểu nguyên thủy).

Vì vậy, Java phá vỡ một nguyên tắc cơ bản của Lập trình chung:
Chúng ta sẽ có thể trao đổi các đối tượng của các kiểu dựng sẵn với các đối tượng của các kiểu do người dùng định nghĩa.
(Bạn có thể tự hỏi: "Anh ấy có nói 'đối tượng tích hợp' không?". Vâng, xem tại đây .)

Về nối chuỗi:

Các nhà toán học sử dụng ký hiệu + cho các phép toán giao hoán trên các tập hợp.
Vì vậy, chúng ta có thể chắc chắn rằng a + b = b + a.
Nối chuỗi (trong hầu hết các ngôn ngữ lập trình) không tôn trọng ký hiệu toán học phổ biến này.

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

hoặc trong Java:

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

Thêm:
Lưu ý làm thế nào trong sự bình đẳng và nhận dạng Java bị nhầm lẫn. Ký hiệu == (đẳng thức) có nghĩa là:
a. Bình đẳng cho các loại nguyên thủy.
b. Do đó, kiểm tra danh tính cho các loại do người dùng xác định, do đó, chúng tôi buộc phải sử dụng hàm bằng () cho đẳng thức.
Nhưng ... Điều này có liên quan gì đến việc quá tải toán tử?
Nếu ngôn ngữ cho phép toán tử quá tải, người dùng có thể đưa ra ý nghĩa chính xác cho toán tử đẳng thức.


Biểu tượng ==được sử dụng cho sự bình đẳng trong Java, như trong C và C ++. Điều này không có gì để làm với quá tải toán tử.
Hot Licks

2
Toán tử ==, trong Java chỉ có nghĩa là Bình đẳng cho các kiểu nguyên thủy. Đối với loại do người dùng định nghĩa có nghĩa là Danh tính. Trong C ++, ngữ nghĩa được xác định bởi người dùng, nhưng nên bảo tồn ngữ nghĩa tích hợp, đẳng thức. Chuỗi a = "xin chào"; Chuỗi b = "xin chào"; boolean c = (a == b);
Fernando Pelliccioni

3
Vì vậy, những gì bạn nói trong nhận xét đầu tiên của bạn là sai. Đúng? Xin vui lòng, cho tôi biết cách kiểm tra sự bình đẳng và danh tính trên các loại do người dùng xác định trong C. Bạn nói đúng, nhận xét của tôi về sự bình đẳng là OT, nhưng tôi đã làm rõ điều đó (xem phần "bổ sung"). Việc tôi chưa tạo ra ngôn ngữ lập trình không có nghĩa là tôi không thể chỉ trích ngôn ngữ hiện có. Tôi xin lỗi nếu bạn đã xem những lời chỉ trích là một cuộc chiến tôn giáo.
Fernando Pelliccioni

1
Đặt những điều dài ngắn: java hút.
Kolya Ivankov


6

Chỉ cần sử dụng Xtend cùng với mã Java của bạn. Nó hỗ trợ quá tải toán tử:

    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
    }

}

Trên trang web chính thức, có một danh sách các phương pháp để thực hiện cho mỗi nhà khai thác!


5

Hoặc, bạn có thể tạo Java Groovy và chỉ cần quá tải các hàm này để đạt được những gì bạn muốn

//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

Ai không muốn / sử dụng Groovy? : D

Không, bạn không thể sử dụng các JAR Groovy đã biên dịch trong Java theo cùng một cách. Nó vẫn là một lỗi biên dịch cho Java.


1

Không giống như C ++, Java không hỗ trợ quá tải toán tử do người dùng định nghĩa. Quá tải được thực hiện trong nội bộ java.

Chúng ta có thể lấy +(cộng) ví dụ:

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

Ở đây, cộng thêm hai số nguyên và nối hai chuỗi. Vì vậy, chúng ta có thể nói rằng Java hỗ trợ quá tải toán tử nội bộ nhưng không do người dùng định nghĩa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.