2009-12-27 17 views
70

¿Por qué tenemos la longitud de una matriz como atributo, array.length, y para Cadena tenemos un método, str.length()?longitud y longitud() en Java

¿Hay alguna razón?

+3

Se ha discutido anteriormente en CodeRanch. Vea la discusión [aquí.] (Http://www.coderanch.com/t/383558/Java-General/java/String-length-vs-Arrays-length) – missingfaktor

Respuesta

23

Un poco simplificado se puede pensar que las matrices son un caso especial y no las clases ordinarias (un poco como las primitivas, pero no). String y todas las colecciones son clases, de ahí los métodos para obtener tamaño, longitud o cosas similares.

Supongo que el motivo en el momento del diseño era el rendimiento. Si lo hubieran creado hoy, probablemente hayan encontrado algo así como clases de colección con respaldo de matriz.

Si alguien está interesado, aquí es un pequeño fragmento de código para ilustrar la diferencia entre los dos en el código generado, primero la fuente:

public class LengthTest { 
    public static void main(String[] args) { 
    int[] array = {12,1,4}; 
    String string = "Hoo"; 
    System.out.println(array.length); 
    System.out.println(string.length()); 
    } 
} 

El corte de una forma en que la parte no tan importante del código de bytes , corriendo javap -c en los resultados de la clase en el siguiente para las dos últimas líneas:

20: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
23: aload_1 
24: arraylength 
25: invokevirtual #4; //Method java/io/PrintStream.println:(I)V 
28: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
31: aload_2 
32: invokevirtual #5; //Method java/lang/String.length:()I 
35: invokevirtual #4; //Method java/io/PrintStream.println:(I)V 

en el primer caso (20-25) el código sólo pide a la JVM para el tamaño de la matriz (en JNI esto tendría sido una llamada a GetArrayLength()) mientras que en th e String case (28-35) necesita hacer una llamada de método para obtener la longitud.

A mediados de la década de 1990, sin buenos JIT y otras cosas, hubiera matado el rendimiento totalmente para tener solo el java.util.Vector (o algo similar) y no una construcción de lenguaje que realmente no se comportara como una clase, sino fue rápido. Por supuesto, pudieron haber enmascarado la propiedad como una llamada a método y manejarlo en el compilador, pero creo que habría sido aún más confuso tener un método en algo que no es una clase real.

+1

Java trata la matriz como objetos y cadenas como objetos inmutables !! : | –

+0

@Myth: no veo su punto ... La propiedad de longitud de las matrices no es un campo público ni nada, es una construcción de la jvm (la longitud de la matriz es incluso una operación en el bytecode). Es muy obvio cuando haces JNI o ​​si simplemente desmontas el código de donde viene. – Fredrik

2

En Java, una matriz almacena su longitud por separado de la estructura que contiene los datos. Cuando crea una matriz, especifica su longitud, y eso se convierte en un atributo definitorio de la matriz. No importa lo que haga a una matriz de longitud N (valores de cambio, cosas nulas, etc.), siempre será una matriz de longitud N.

La longitud de una cadena es incidental; no es un atributo de la Cadena, sino un subproducto. Aunque las cadenas de Java son, de hecho, inmutables, si fuera posible cambiar su contenido, podría cambiar su longitud. Golpear el último carácter (si fuera posible) reduciría la longitud.

Entiendo que esta es una buena distinción, y es posible que me voten a favor, pero es verdad. Si hago una Matriz de longitud 4, esa longitud de cuatro es una característica definitoria de la Matriz, y es verdadera independientemente de lo que contenga. Si hago una cadena que contenga "perros", esa cadena tiene una longitud de 4 porque contiene cuatro caracteres.

Veo esto como una justificación para hacer una con un atributo y la otra con un método. En verdad, puede ser una inconsistencia involuntaria, pero siempre tiene sentido para mí, y así es como lo he pensado.

1

Me enseñaron que para matrices, la longitud no se recupera mediante un método debido al siguiente temor: los programadores asignarían la longitud a una variable local antes de ingresar un bucle (piense en un bucle donde el condicional usa la longitud de la matriz .) El programador supuestamente lo haría para recortar en las llamadas a funciones (y de ese modo mejorar el rendimiento). El problema es que la longitud podría cambiar durante el ciclo, y la variable no.

+0

Buen punto ..... – Zaki

+10

La longitud de una matriz no puede cambiar durante el ciclo. – Fredrik

+2

no puede cambiar la longitud de esta matriz en particular, pero puede asignar una nueva a la misma variable – Bozho

5

considerar:

int[] myArray = new int[10]; 
String myString = "hello world!"; 
List<int> myList = new ArrayList<int>(); 

myArray.length // Gives the length of the array 
myString.length() // Gives the length of the string 
myList.size()  // Gives the length of the list 

Es muy probable que cadenas y matrices fueron diseñados en diferentes momentos y por lo tanto terminaron usando diferentes convenciones. Una justificación es que, como Strings usa matrices internamente, se utilizó un método, length(), para evitar la duplicación de la misma información. Otra es que el uso de un método length() ayuda a enfatizar la inmutabilidad de las cadenas, aunque el tamaño de una matriz tampoco se puede modificar.

En última instancia, esta es solo una inconsistencia que evolucionó y que definitivamente se solucionaría si alguna vez se rediseñara el lenguaje desde cero. Hasta donde yo sé, no hay otros idiomas (C#, Python, Scala, etc.) que hagan lo mismo, por lo que es probable que se trate de un pequeño error que terminó como parte del lenguaje.

Recibirá un error si utiliza el incorrecto de todos modos.

+0

Esta es una respuesta más justificada e imparcial. –

0

Cada vez que se crea una matriz, se especifica su tamaño. Entonces la longitud se puede considerar como un atributo de construcción. Para String, es esencialmente una matriz de caracteres. La longitud es una propiedad de la matriz de caracteres. No hay necesidad de poner longitud como un campo, porque no todo necesita este campo. http://www.programcreek.com/2013/11/start-from-length-length-in-java/

72

Permítanme primero resaltar tres formas diferentes para fines similares.

length - matrices (int[], double[], String[]) - Conocer la longitud de las matrices

length() - Cadena relacionados Objeto (String, StringBuilder, etc) - para conocer la longitud de la cadena

size() - colección de objetos (ArrayList, Set, etc.) - para saber el tamaño de la Colección

Ahora olvídate de length() considera solo length y size().

length no es un método, por lo que tiene sentido que no funcione en los objetos. Solo funciona en arreglos.
size() su nombre lo describe mejor y, como es un método, se usará en el caso de los objetos que trabajan con la colección (marcos de recopilación) como dije arriba.

Ahora vienen a length():
cadena no es una matriz primitiva (lo que no podemos utilizar .length) y tampoco una colección (así que no puedo usar .size()) por eso también tenemos una diferente, que es length() (mantenga las diferencias y cumpla el propósito).

Como respuesta a ¿Por qué?
Me resulta útil, fácil de recordar y usar y amigable.

+2

¡solución increíble! –

6

.length es una propiedad única de Java.Se usa para encontrar el tamaño de una única dimensión array.

.length() es un método. Se usa para encontrar la longitud de String. Evita duplicar el valor.

-1

Solo quiero agregar algunas observaciones al gran answer por Fredrik.

Los Java Language Specification in Section 4.3.1 estados

Un objeto es un ejemplo clase o un array.

Así que la matriz tiene un papel muy especial en Java. Me pregunto por qué.

Se podría argumentar que la matriz de implementación actual es/era importante para un mejor rendimiento. Pero que es una estructura interna, que no debe ser expuesta.

Claro que también podrían haber enmascarado la propiedad como una llamada de método y manejado en el compilador, pero creo que habría sido aún más confuso tener un método en algo que no es una clase real.

Estoy de acuerdo con Fredrik, que una optimazación del compilador inteligente habría sido la mejor opción. Esto también resolvería el problema, que incluso si usa una propiedad para matrices, no ha resuelto el problema para cadenas y otros tipos de colecciones (inmutables), porque, por ejemplo, string se basa en una matriz char como puede ver en definición de clase de String:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {   
    private final char value[]; // ... 

Y no estoy de acuerdo con que sería aún más confuso, porque no heredará gama all methods from java.lang.Object.

Como ingeniero, realmente no me gusta la respuesta "Porque siempre ha sido así". y deseó que hubiera una mejor respuesta. Pero en este caso parece ser.

tl; dr

En mi opinión, se trata de un defecto de diseño de Java y no debería haber implementado esta manera.

Cuestiones relacionadas