Cap 4 - kathy segunda edicao - erro

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…

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?

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

[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.

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

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

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?

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

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

[quote=camilolopes]

/* qdo quiser comparara referencia de um tipo == qdo quiser comparar se dois objeto sao iguais equals()*/ [/quote]
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.

[quote=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.*/ [/quote]
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.

[quote=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?*/ [/quote]
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.