Cap 4 - kathy segunda edicao - erro

9 respostas
LPJava

ae pessoal ontem estudando o livro da kathy me deparei uma situação que me confudiu no uso do == e metodo equals()… veja a sintaxe…

class EnumEqual{
	enum Color { RED, AZUL};
	enum Car{ CELTA, BMW};
	public static void main(String [] ags){
		Color c = Color.RED;
		Color c2 = Color.AZUL;
		Color c3=c;
		
		Car ca = Car.CELTA;
		Car bw = Car.BMW;
		Car carr = ca;
		
		if(c==c3){System.out.println("==");}
		
		if(ca.equals(carr)){System.out.println("equals Enum Car");}
		
	}
}

/* qdo quiser comparara referencia de um tipo ==
qdo quiser comparar se dois objeto sao iguais equals()*/

/*o que pude entender aqui que enum nao sao objetos eh um tipo de
variavel que posso comparar com referencia semelhante a comparar se
Moto m = new Moto(); Moto mt = new Moto();
entao no exemplo acima to comparando  se as varaiaveis enum referencia a outra
e nao se sao objetos? seria isso.*/

/* entao a pag 166 da kathy em port ta errada ela diz que se usar
 = = com referencia diferente imprime verdadeiro, ja que no exemplo dela
 eu tenho duas variaveis do tipo enum porem com referencia diferente e o codigo 
 dizendo ela retorna verdade no seria falso?*/

Bom eu modifiquei a class dela para sabe se eu q to errado ou eh mais um erro do livro iai o q vcs me diz?

Aproveitei e fiz uma class para tentar tirar minha duvida:

class Enu{
	enum Nome{ CAMILO, NETO}
	public static void main(String args[]){		
		//aqui n2 refere-se a n1 recebe o mesma constante
		Nome n1 = Nome.CAMILO;
		Nome n2 = Nome.CAMILO;
		
		//é a mesma coisa que acima
		int a = 10;
		int b = 10;
		
	//é do mesmo tipo porem uma referencia diferente 
		Nome n3 = Nome.NETO;
		
		
		System.out.println(n1==n2); //true
		System.out.println(a==b); // true
		System.out.println(n3==n1); //false
	}
}
/*então enum eh um tipo, mais nao eh um objeto*/

flw!!! comentem ai…

9 Respostas

Mantu

Enums são objetos sim.
O que eu acho que acontece é o seguinte: Os elementos de um enum MeuEnum, por exemplo, são na verdade campos públicos, constantes e estáticos de MeuEnum. A além disso, o tipo desses “campos” são subclasses da classe de MeuEnum.
É como se o enum abaixo:

public enum Colors{
   BLACK,
   WHITE
}

fosse algo parecido com isso aqui:

public abstract class Colors{
   public static final ColorsWhite WHITE = new ColorsWhite();
   public static final ColorsBlack BLACK = new ColorsBlack();

   public static class ColorsWhite extends Colors{
      ...
   }

   public static class ColorsBlack extends Colors{
      ...
   }
}

Por favor, corrijam as besteiras que eu tenha dito, ok?

LPJava

é mais o que acontece no exemplo que citei, la da kathy…

Mantu

[size=18][color=red]SE O QUE EU DISSE ESTIVER CERTO[/color][/size], então o que acontece é o seguinte:
Imagine o seguinte trecho

Colors cor01 = Colors.BLACK;
Colors cor02 = Colors.BLACK;

System.out.println(cor01 == cor02);

isso vai imprimir na tela true. Por quê? Porque Sempre que você faz Colors.BLACK, você está pegando sempre o mesmo objeto. Não uma nova instanciação a cada vez que você chama Color.BLACK.

LPJava

então meus comentarios tá certo, e o livro ta errado…

Sami_Koivu

Olá,

O que você disse tá certo, Mantu (com a exceção que os campos não são subclasses). O enum compilado fica mais ou menos assim:

public final class Colors extends Enum {
    public static final Colors WHITE = new Colors("WHITE", 0);
    public static final Colors BLACK = new Colors("BLACK", 1);
 

    public Colors(String str, int i) {
        ...
    }

...

}

[]s,
Sami

Mantu

Eu imagino que são subclasses, por que podemos fazer umas loucuras do tipo:

import java.util.Calendar;

public enum ECampoData {
	DIA{
		public int eval() {
			return Calendar.DAY_OF_MONTH;
		}
	},
	MES{
		public int eval() {
			return Calendar.MONTH;
		}
	},
	ANO{
		public int eval() {
			return Calendar.YEAR;
		}
	},
	HORA{
		public int eval() {
			return Calendar.HOUR_OF_DAY;
		}
	},
	MINUTO{
		public int eval() {
			return Calendar.MINUTE;
		}
	}
	;
	public abstract int eval();
}

Tipo, está havendo aí - pelo menos de forma aparente - uma relação polimórfica entre o tipo enumerado ECampoData e seus elementos. Por isso imaginei os elementos como subclasses (classes filhas) do tipo enumerado. Tá errado esse raciocínio?

Sami_Koivu

Não está errado, não. Eu que não estava pensando num caso desses. Nesse caso, sim, seria uma subclasse (anônima).

Algo tipo:

public abstract class ECampoData extends Enum {

    ECampoData DIA = new ECampoData("DIA", 0) {
 		public int eval() {
 			return Calendar.DAY_OF_MONTH;
 		}
    };

   ...
}

Mas o tipo do campo permanece o tipo do enum.

[]s,
Sami

Sami_Koivu

Quanto à dúvida do colega Camilo, daria pra citar esse trecho do livro que você diz estar com erro?

Mantu

camilolopes:

/* qdo quiser comparara referencia de um tipo == qdo quiser comparar se dois objeto sao iguais equals()*/


Não entendi direito o que você quis dizer, mas, de qualquer forma, lá vai:
Quando estamos comparando dois objetos, utilizamos:
:arrow: == para verificar se os objetos comparados são, na verdade, o mesmo objeto.
:arrow: equals para verificar se um objeto é equivalente ao outro objeto. Note que o critério que define se um objeto (o que invoca o equals) é equivalente ao outro objeto (o que é passado por parâmetro) depende exclusivamente da implementação do método equals dada pela classe do objeto que invoca o equals.

camilolopes:
/*o que pude entender aqui que enum nao sao objetos eh um tipo de variavel que posso comparar com referencia semelhante a comparar se Moto m = new Moto(); Moto mt = new Moto(); entao no exemplo acima to comparando se as varaiaveis enum referencia a outra e nao se sao objetos? seria isso.*/

Desculpe, mas não consegui entender o que vc escreveu aqui… vou tentar advinhar, ok?
Como já disse antes, enums são objetos sim! O que define se uma variável é ou não um objeto (O apropriado a se dizer seria: “faz referência ou não a um objeto”), não é o fato de se compará-lo usando == ou equals. Isso não tem nada a ver. O que define se uma variável é um ou não um objeto, é se ela é de algum tipo de dado que seja subclasse de Object.
Do jeito que você fez seu exemplo, dá a entender que Moto é alguma classe aí que você inventou. Sendo assim, supondo que temos a situação por você mencionada:

Moto m = new Moto();
Moto mt = new Moto();

Podemos comparar se m é a mesma instância que mt utilizando o operador “==”:

boolean ehMesmaInstancia = m == mt;

Ou então, podemos comparar se m é equivalente a mt utilizando o método equals:

boolean saoEquivalentes = m.equals(mt);

Ja podemos saber de antemão que a variável ehMesmaInstancia vai ser false, pois m e mt foram criados, cada um, com um new diferente. Agora, se a variavel saoEquivalentes vai ser true ou false, vai depender de como você sobrescreveu o método equals na classe Moto.

camilolopes:
/* entao a pag 166 da kathy em port ta errada ela diz que se usar = = com referencia diferente imprime verdadeiro, ja que no exemplo dela eu tenho duas variaveis do tipo enum porem com referencia diferente e o codigo dizendo ela retorna verdade no seria falso?*/

camilolopes, por favor, tente utilizar virgulas quando você escrever, pois fica muito difícil de entender o que você quer dizer quando escreve assim… :roll:
Essa parte da sua questão se explica com o que já foi discutido aqui antes:
Vamos supor o seguinte enum:

enum Color{RED, BLUE};

O elemento RED do enum Color - o qual não deixa de ser uma classe - é de um objeto de uma classe anônima, filha da classe Color. Este elemento RED é também publico, estático e constante. Isso quer dizer o seguinte:
:arrow: Você sempre pode obter o objeto RED diretamente a partir da classe Color (Você não precisa de uma instância de Color, para obter o elemento RED)
:arrow: O elemento RED vai sempre referenciar um único e mesmo objeto (Por ser final, RED nunca mais poderá apontar para outro objeto), o qual é de uma classe anônima, filha de Color.
Sendo assim, se tivermos o seguinte trecho:

Color cor01 = Color.RED;
Color cor02 = Color.RED;

Podemos raciocinar da seguinte maneira: Se Color.RED sempre, sempre, vai referenciar um mesmo objeto, então cor01 e cor02 estão, na verdade, apontando para o mesmo objeto que Color.RED. Isso quer dizer que cor01 e cor02 apontam para um mesmo objeto (usualmente, diriamos que cor01 e cor02 são uma mesma instância, um mesmo objeto). Sendo assim, cor01 == cor02, de fato, retorna true.

Criado 30 de janeiro de 2007
Ultima resposta 30 de jan. de 2007
Respostas 9
Participantes 3