A segurança de tipos pode impedir certas construções válidas, como comparar valores absolutos de diferentes tipos numéricos.
Um exemplo é o método
absEqual(), que verifica se dois objetosNumericFnscontêm números com valores absolutos iguais, mesmo que sejam de tipos diferentes, comoDoubleeFloat.O método compara o valor absoluto do objeto chamador com o do argumento passado.
NumericFns<Double> dOb = new NumericFns<Double>(1.25);
NumericFns<Float> fOb = new NumericFns<Float>(-1.25);
if(dOb.absEqual(fOb))
System.out.println("Absolute values are the same.");
else
System.out.println("Absolute values differ.");
Criar o método
absEqual()parece simples, mas surgem problemas ao definir o parâmetro de tipo paraNumericFns.A dúvida está em qual tipo usar como parâmetro de
NumericFns, já que ele deve lidar com diferentes tipos numéricos.Uma solução inicial seria usar o mesmo tipo genérico
T, mas isso pode não atender a todos os casos.
Exemplo: Example1.java
// Este código não funcionará!
// Determina se os valores absolutos de dois objetos são iguais.
boolean absEqual(NumericFns<T> ob) {
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue()) return true;
return false;
}
Usar
Math.abs()para comparar valores absolutos emabsEqual()só funciona se ambos os objetosNumericFnsforem do mesmo tipo, comoNumericFns<Integer>.Essa abordagem não é genérica e impede a comparação entre diferentes tipos, como
NumericFns<Integer>eNumericFns<Double>.Para criar uma solução genérica, utiliza-se o argumento curinga
(?), que representa um tipo desconhecido em Java.
// Determina se os valores absolutos de
// dois objetos são iguais.
boolean absEqual(NumericFns<?> ob) { // Observe o curinga.
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue())) return true;
return false;
}
NumericFns<?>permite comparar dois objetosNumericFnsde qualquer tipo, tornando o método genérico.Isso possibilita a comparação de valores absolutos entre objetos
NumericFnscom diferentes tipos numéricos.
// Usa um curinga.
class NumericFns<T extends Number> {
T num;
// Passa para o construtor uma referência
// a um objeto numérico.
NumericFns(T n) {
num = n;
}
// Retorna o recíproco.
double reciprocal() {
return 1 / num.doubleValue();
}
// Retorna o componente fracionário.
double fraction() {
return num.doubleValue() - num.intValue();
}
// Determina se os valores absolutos de
// dois objetos são iguais.
boolean absEqual(NumericFns<?> ob) {
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue())) return true;
return false;
}
// ...
}
// Demonstra um curinga.
class WildcardDemo {
public static void main(String args[]) {
NumericFns<Integer> iOb =
new NumericFns<Integer>(6);
NumericFns<Double> dOb =
new NumericFns<Double>(-6.0);
NumericFns<Long> lOb =
new NumericFns<Long>(5L);
System.out.println("Testing iOb and dOb.");
// Nesta chamada, o tipo curinga equivale a Double.
if(iOb.absEqual(dOb))
System.out.println("Absolute values are equal.");
else
System.out.println("Absolute values differ.");
System.out.println();
System.out.println("Testing iOb and lOb.");
// Nesta chamada, o curinga equivale a Long.
if(iOb.absEqual(lOb))
System.out.println("Absolute values are equal.");
else
System.out.println("Absolute values differ.");
}
}
Observe estas duas chamadas a absEqual( ):
if(iOb.absEqual(dOb))
if(iOb.absEqual(lOb))Com o curinga
(<?>), é possível chamarabsEqual()com objetosNumericFnsde tipos diferentes, comoNumericFns<Integer>eNumericFns<Double>, ouNumericFns<Long>.O curinga não altera os tipos permitidos para criar objetos
NumericFns; isso continua sendo controlado pela cláusula extends na declaração.Ele apenas permite que qualquer objeto válido de
NumericFnsseja usado no método.
Top comments (0)