s1 == ""
no es fiable, ya que pone a prueba la igualdad de referencia se opone la igualdad (y la cadena no es estrictamente canónica).
s1.equals("")
es mejor, pero puede sufrir excepciones de puntero nulo. Mejor aún es:
"".equals(s1)
Sin excepciones de punteros nulos.
EDITAR: Bien, se preguntó sobre el punto canonical form. Este artículo lo define como:
Supongamos que tenemos algún conjunto S de objetos, con una relación de equivalencia. Una forma canónica se da al designar algunos objetos de S para que sean "en forma canónica ", de modo que cada objeto bajo consideración es equivalente exactamente a un objeto en forma canónica.
Para darle un ejemplo práctico: tome el conjunto de números racionales (o "fracciones" como se llaman comúnmente). Un número racional consiste en un numerador y un denomoinator (divisor), ambos son enteros. Estos números racionales son equivalentes:
3/2, 6/4, 24/16
nubmers racionales son típicamente escritos de tal manera que el mcd (máximo común divisor) es 1. Así que todos ellos se simplificará a 3/2. 3/2 se puede ver como forma canónica de este conjunto de números racionales.
Entonces, ¿qué significa en programación cuando se usa el término "forma canónica"? Puede significar un par de cosas. Tomemos por ejemplo esta clase imaginaria:
public class MyInt {
private final int number;
public MyInt(int number) { this.number = number; }
public int hashCode() { return number; }
}
El código hash de la clase myInt es una forma canónica de esa clase ya que para el conjunto de todas las instancias de myInt, puede tomar cualquiera de los dos m1 elementos y m2 y lo harán obedezca la siguiente relación:
m1.equals(m2) == (m1.hashCode() == m2.hashCode())
Esa relación es la esencia de la forma canónica. Una forma más común de esta surge es cuando se utiliza métodos de fábrica en clases tales como:
public class MyClass {
private MyClass() { }
public MyClass getInstance(...) { ... }
}
instancias no se pueden crear instancias directamente porque el constructor es privado. Este es solo un método de fábrica. Lo que un método de fábrica le permite hacer es cosas como:
- Devolver siempre la misma instancia (singleton abstraído);
- Simplemente crea una nueva intsance con cada llamada;
- Devuelve objetos en forma canónica (más sobre esto en un segundo); o
- lo que quieras.
Básicamente, el método de fábrica abstrae la creación de objetos y, personalmente, creo que sería una característica de lenguaje interesante forzar a todos los constructores a ser privados para imponer el uso de este patrón, pero estoy divagando.
Lo que puede hacer con este método de fábrica es caché de las instancias que se crea tal que para cualesquiera dos casos S1 y S2 obedecen a la siguiente prueba:
(s1 == s2) == s1.equals(s2)
Así que cuando digo cadena no es estrictamente canónica que significa que:
String s1 = "blah";
String s2 = "blah";
System.out.println(s1 == s2); // true
Pero, como otros han poitned OUT puede cambiar esto usando:
String s3 = new String("blah");
y posiblemente:
String s4 = String.intern("blah");
Así que no se puede confiar en la igualdad de referencia completamente por lo que no debe confiar en ella en absoluto.
Como advertencia al patrón anterior, debo señalar que controlar la creación de objetos con constructores privados y métodos de fábrica no garantiza que la igualdad de referencia signifique igualdad de objetos debido a la serialización. La serialización evita el mecanismo normal de creación de objetos. Josh Bloch cubre este tema en Effective Java (originalmente en la primera edición cuando habló sobre el patrón de ensafe tipo seguro que más tarde se convirtió en una característica del lenguaje en Java 5) y puede evitarlo al sobrecargar el método (privado) readResolve(). Pero es complicado. Los cargadores de clases también afectarán el problema.
De todos modos, eso es forma canónica.
¿No está comparando la longitud mejor manera? Creo que la comparación de longitud está más optimizada que la comparación de cadenas – Ravisha
@Ravisha Internally, ['String.java''s] (http://www.docjar.com/html/api/java/lang/String.java.html)' El método equals' tiene varias optimizaciones: ** 1: ** Referencia '==' comparación, ** 2: ** 'instancia de cadena de verificación antes del casting, y ** 3: ** longitud del valor de comparación antes de finalmente comparar las cadenas charachter por personaje Entonces, para responder a su pregunta, sí, la comparación de longitud es eficiente, pero su código debe confiar en String.equals y no reinventar ninguna de sus ruedas. –
@Patrick M. Si la intención aquí es verificar la cadena vacía, prefiero comparar la longitud. En lugar de comparación. – Ravisha