¿Por qué los diseñadores de Java no crearon versiones estáticas de métodos de manipulación de cadenas en la java.lang.String
clase? A los que me refiero son los siguientes métodos, pero la pregunta también puede extenderse a otros métodos no estáticos en la clase.
concat(String) substring(int, int)
replace(char, char) toLowerCase()
replace(CharSequence, CharSequence) toLowerCase(Locale)
replaceAll(String, String) toString()
replaceFirst(String, String) toUpperCase()
split(String) toUpperCase(Locale)
split(String, int) trim()
substring(int)
Tener solo versiones no estáticas de estos métodos obliga a la comprobación nula explícita en cualquier lugar al que deba llamarse dicho método. Por ejemplo, simplemente llamar example = example.trim()
conduciría a NullPointerException si String example = null
. Por lo tanto, el programador tiene que hacer la siguiente comprobación nula repetitiva:
if (example != null)
example = example.trim();
// OR:
example = (example==null) ? null : example.trim();
example = (example==null) ? null : example.substring(5);
Me imagino que habría sido mucho más conveniente si String
hubiera versiones estáticas de estos métodos (quizás incluso exclusivamente ), que tomarían la cadena de entrada como primer argumento:
example = String.trim(example);
example = String.replace(example, 'a', 'b');
example = String.substring(example, 5);
Esto habría llevado a un código más limpio escrito por programadores que se habría ocupado automáticamente de los casos nulos simplemente devolviendo nulo, en lugar de obligar a los programadores a manejar explícitamente los casos nulos. La devolución de nulo tiene sentido para mí, ya que manipular una cadena nula debería dar como resultado una cadena nula , no un error.
¿Por qué los diseñadores de Java no pensaron en esto cuando diseñaron la String
clase en Java 1 o Java 2, o incluso agregaron esa funcionalidad en una versión posterior de Java?
fuente
null
es un estado excepcional y debe manejarse explícitamente.Maybe<T>
tipo, supongo.string name = employee?.personalData?.name
. Solo como un atajo para todos estosif (employee != null)
s repetitivos . Pregunta SO relacionada: stackoverflow.com/questions/1196031/…Respuestas:
Bueno, esa es tu opinión. Otros pueden argumentar que las operaciones de cadena en un objeto nulo, que no contiene una cadena, no tienen sentido y, por lo tanto, deberían arrojar una excepción
Por qué los "diseñadores de Java" hicieron o no hicieron algo es difícil de responder.
Ya hay bibliotecas por ahí que pueden realizar operaciones de cadena nulas, por ejemplo, StringUtils de Apache Commons. Puede usar eso o bibliotecas similares si las necesita.
Adición basada en tus comentarios
Al leer los comentarios, parece que el verdadero problema que enfrenta es que debe verificar
null
todo el código. Eso puede ser un indicador de un mal diseño del programa sin contratos claramente definidos entre las interfaces. Es posible que desee leer Evitar "! = Null" declaraciones en Java?fuente
Optional
- code.google.com/p/guava-libraries/wiki/…En mi opinión, todo el enfoque "si arg es nulo devuelve nulo" a los métodos de escritura aumenta innecesariamente la complejidad ciclomática de su programa.
Las primeras bibliotecas de Java usaban el enfoque de retorno nulo, pero los chicos de JDK siempre se protegían contra nulo con excepciones.
Con el tiempo, creo que este último enfoque ha resultado ser el claro ganador.
¿Por qué? Dado que los campos nulos rompen muchos principios oo. Simplemente no puede tratarlos como miembros de una clase polimórfica. Esto significa que siempre debe codificar casos especiales para nulo y, por lo tanto, su complejidad ciclomática se dispara cuando tiene que suponer que las cosas pueden ser nulas.
Para resolver sus problemas, considere usar el patrón de objeto nulo en lugar de confiar en campos nulos.
fuente
String
no es polimórfico, ¿no? ¿Y cómo utiliza el patrón de objeto nulo para un tipo ya existente como String?int
predeterminado es cero en lugar denull
. Conceptualmente, debería ser posible tener unstring
tipo cuyo valor predeterminado sería una cadena vacía en lugar denull
[dicho tipo podría ser semánticamente paraString
lo queint
esInteger
]. El hecho de que un no vacíostring
contenga internamente una referencia a un objeto de montón sería un detalle de implementación; no hay razón para que no pueda comportarse semánticamente como un primitivo.No digo que esta sea la razón, pero a excepción de toString, todos estos métodos se encapsulan fácilmente en una clase auxiliar estática, mientras que lo contrario no es cierto.
Es decir, si desea Stings.toUpper (entrada de cadena), el código para eso es fácil de escribir, pero si desea instance.toUpper y todo lo que tiene es String.toUpper, bueno, eso es imposible ... a menos que introduzcan métodos de extensión, que probablemente ni siquiera se consideró en ese momento.
fuente
String.format
(estático), pero no puede hacerlo"something %s".format(id)
.En java, esa cadena es un objeto. Esa es una elección de diseño.
Las referencias a objetos pueden ser nulas y son nulas si no hay ningún objeto asignado. Si llama a dicho objeto, se produce una NullPointerException. Ese es el comportamiento estándar.
Los diseñadores de Java eligieron tener cadenas como objeto y que esos métodos arrojen excepciones de puntero nulo es lo que obtienes si quieres que las cadenas sean objetos.
Probablemente lo pensaron y decidieron incorporar el comportamiento oo.
fuente
String.format
. (Lo mismo en C #, por cierto). Entonces, si esa es una opción de diseño, no puede provenir únicamente del hecho de que las cadenas son objetos, y no se aplica de manera consistente.Strings
clase de utilidad, como si tuviéramos unaArrays
clase de utilidad ( aunque entiendo que se creó por pura necesidad debido a que las matrices son una especie de cruce extraño entre primitivas y objetos: ) ) ... siempre que fuera parte de Java estándar y no requiriera dependencias.