Sobrecarga de operador em Java

Respostas:

235

Não, o Java não suporta sobrecarga de operador definida pelo usuário. O único aspecto do Java que se aproxima da sobrecarga "personalizada" do operador é o tratamento de + para seqüências de caracteres, o que resulta em concatenação de constantes em tempo de compilação ou concatenação em tempo de execução usando StringBuilder / StringBuffer. Você não pode definir seus próprios operadores que agem da mesma maneira.

Para uma linguagem Java-like (e baseado em JVM), que faz a sobrecarga de operador de suporte, você pode olhar para Kotlin ou Groovy . Como alternativa, você pode ter sorte com uma solução de plug-in do compilador Java .

Jon Skeet
fonte
4
Você está dizendo que não podemos criar wrapper em java? Tais como SmallInteger como Integer?
huseyin tugrul buyukisik 12/09/12
3
@ tuğrulbüyükışık: Já existem wrappers para todos os tipos primitivos existentes - mas se você quisesse criar seu próprio novo tipo de wrapper, não seria capaz de fazê-lo se comportar como os outros, pois eles têm suporte específico no idioma.
22812 Jon Skeet
1
obrigado, pesquisei no Google e não consegui encontrar. Eu queria saber se eu poderia fazer uma variável complexa composta de duas primitivas (um duplo e um int ---> boa precisão + alcance bom)
huseyin Tugrul buyukisik
40
@djaqeel: a sobrecarga do operador torna o código menos legível quando mal utilizado . Quando bem utilizado, pode melhorar bastante a legibilidade da IMO. Observe o código usado BigIntegerem Java e, BigIntegerem C #, usando operadores. Não vejo como os delegados violam os princípios de POO - você precisa ser muito mais preciso do que isso em suas objeções. Não sei os detalhes de por que os designers de Java não incluíram vários recursos, mas suspeito que haja uma mistura de pressão de recursos e um desejo de manter a linguagem pequena e relativamente simples.
Jon Skeet
4
Eu sei que é tarde, mas um exemplo vale mais que mil argumentos. Dado m0como um Matrixe v0, v1, v2, v3, e v4como Vectors, simplesmente comparar o tempo que você leva para corretamente interpretar a seguinte expressão matemática m0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);. Se o suporte à sobrecarga do operador tivesse sido incluído, poderia ter sido escrito como m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;.
code_dredd
38

A sobrecarga do operador é usada em Java para a concatenação do tipo String:

String concat = "one" + "two";

No entanto, você não pode definir suas próprias sobrecargas de operador.

teabot
fonte
26

Além de todas as pessoas que apontam que +está sobrecarregado para Strings, -também está sobrecarregado para operações de ponto flutuante e número inteiro, como são *e /.

[edit] %também está sobrecarregado para ponto flutuante, o que pode ser uma surpresa para quem tem um background em C ou C ++.

MSalters
fonte
21

Java não permite sobrecarga do operador. A abordagem preferida é definir um método em sua classe para executar a ação: em a.add(b)vez de a + b. Você pode ver um resumo dos outros bits que o Java deixou de fora das linguagens C, aqui: Recursos removidos de C e C ++

roubar
fonte
2
O importante é o objetivo do design de tornar os arquivos de origem Java independentes do contexto. Tentando ler muito grande (MLOC), programas macro pesados ​​C têm uma curva de aprendizado muito longa. Um programa Java comparável (ou maior) não é mais difícil de mergulhar do que um pequeno programa Java. Como disse Gosling: Uma língua para azuis programadores colarinho para trabalhar em [E quem pensa clichê verbosidade é prejudicial deve ler sobre chunking na cognição especialista.].
Tim Williscroft
2
Graças ao oracle, nenhum dos links java.sun.com funciona. Você pode fornecer o link atualizado, se possível?
Syed Aqeel Ashiq
17

Você não pode fazer isso sozinho, já que o Java não permite a sobrecarga do operador.

Com uma exceção, no entanto. + e + = estão sobrecarregados para objetos String.

Brian Agnew
fonte
8
Existem muitos outros exemplos de sobrecarga de operadores em Java. Por exemplo &, |e ^são sobrecarregar por booleane tipos integrais. E, de fato, os operadores aritméticos e relacionais estão sobrecarregados para vários tipos numéricos. (Claro, a semântica das sobrecargas estão muito mais próximos ...)
Stephen C
16

Como muitos outros responderam: Java não suporta sobrecarga de operador definida pelo usuário.

Talvez isso esteja fora do tópico, mas quero comentar sobre algumas coisas que li em algumas respostas.

Sobre legibilidade.
Comparar:

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

Olhe novamente!
Qual é mais legível?

Uma linguagem de programação que permita a criação de tipos definidos pelo usuário deve permitir que eles ajam da mesma maneira que os tipos internos (ou tipos primitivos).

Portanto, o Java quebra um princípio fundamental da Programação Genérica:
devemos poder trocar objetos de tipos internos com objetos de tipos definidos pelo usuário.
(Você pode estar se perguntando: "Ele disse 'objetos embutidos'?". Sim, veja aqui .)

Sobre a concatenação de String:

Os matemáticos usam o símbolo + para operações comutativas em conjuntos.
Portanto, podemos ter certeza de que a + b = b + a.
A concatenação de strings (na maioria das linguagens de programação) não respeita essa notação matemática comum.

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

ou em Java:

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

Extra:
Observe como em Java a igualdade e a identidade são confusas. O símbolo == (igualdade) significa:
a. Igualdade para tipos primitivos.
b. A verificação de identidade para tipos definidos pelo usuário, portanto, somos forçados a usar a função equals () para igualdade.
Mas ... O que isso tem a ver com sobrecarga do operador?
Se o idioma permitir que o operador sobrecarregue, o usuário poderá dar o significado adequado ao operador de igualdade.

Fernando Pelliccioni
fonte
O símbolo ==é usado para igualdade em Java, como em C e C ++. Isso não tem nada a ver com sobrecarga do operador.
Hot Licks
2
O operador ==, em Java, significa apenas igualdade para tipos primitivos. Para tipos definidos pelo usuário significa Identidade. Em C ++, a semântica é definida pelo usuário, mas deve preservar a semântica interna, a igualdade. String a = "olá"; String b = "olá"; booleano c = (a == b);
Fernando Pelliccioni 11/10
3
Então, o que você disse no seu primeiro comentário está errado. Certo? Por favor, diga-me como testar igualdade e identidade em tipos definidos pelo usuário em C. Você está certo, meu comentário sobre igualdade é OT, mas eu esclarei isso (consulte os "extras"). O fato de eu não ter criado uma linguagem de programação não significa que não posso criticar uma linguagem existente. Lamento se você viu as críticas como uma guerra religiosa.
Fernando Pelliccioni
1
Colocando coisas longas curtas: java é uma merda.
Kolya Ivankov
12

Pode-se tentar a sobrecarga do operador Java . Ele tem suas próprias limitações, mas vale a pena tentar se você realmente deseja usar a sobrecarga do operador.

Alexander Mironov
fonte
6

Basta usar o Xtend junto com o seu código Java. Ele suporta sobrecarga do operador:

    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
    }

}

No site oficial, há uma lista dos métodos a serem implementados para cada operador!

Aurelien B
fonte
5

Ou você pode criar o Java Groovy e sobrecarregar essas funções para obter o que deseja

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

Quem não quer ser / usar groovy? : D

Não, você não pode usar os JARs groovy compilados em Java da mesma maneira. Ainda é um erro do compilador para Java.

conhecidos
fonte
1

Ao contrário do C ++, o Java não suporta sobrecarga de operador definida pelo usuário. A sobrecarga é feita internamente em java.

Podemos pegar +(mais) por exemplo:

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

Aqui, plus adiciona dois números inteiros e concatena duas strings. Portanto, podemos dizer que Java suporta sobrecarga de operador interno, mas não definido pelo usuário.

nayanjyoti sharma
fonte