java - proposito - ¿Por qué una matriz no se puede asignar a Iterable?
proposito de java (4)
con Java5 podemos escribir:
Foo[] foos = ...
for (Foo foo : foos)
o simplemente usando un Iterable en el ciclo for. Esto es muy útil.
Sin embargo, no puede escribir un método genérico para iterable como este:
public void bar(Iterable<Foo> foos) { .. }
y llamarlo con una matriz, ya que no es un Iterable:
Foo[] foos = { .. };
bar(foos); // compile time error
Me pregunto acerca de las razones detrás de esta decisión de diseño.
Desafortunadamente, las matrices no son de " class
suficiente". No implementan la interfaz Iterable
.
Aunque las matrices ahora son objetos que implementan Clonable y Serializable, creo que una matriz no es un objeto en el sentido normal y no implementa la interfaz.
La razón por la que puede usarlos para cada bucle es porque Sun agregó algo de azúcar sintáctica para las matrices (es un caso especial).
Como las matrices comenzaron como ''casi objetos'' con Java 1, sería un cambio demasiado drástico para convertirlos en objetos reales en Java.
La matriz es un Objeto, pero sus elementos pueden no serlo. La matriz puede contener un tipo primitivo como int, que Iterable no puede manejar. Al menos eso es lo que creo.
Las matrices deben admitir Iterable
, simplemente no, por la misma razón que las matrices .NET no admiten una interfaz que permita el acceso aleatorio por posición (no existe tal interfaz definida como estándar). Básicamente, los frameworks a menudo tienen pequeñas lagunas molestas en ellos, que no vale la pena que alguien lo arregle. No importaría si pudiéramos arreglarlos nosotros mismos de una manera óptima, pero a menudo no podemos.
ACTUALIZACIÓN: para ser imparcial, mencioné las matrices .NET que no admiten una interfaz que admite el acceso aleatorio por posición (ver también mi comentario). Pero en .NET 4.5 esa interfaz exacta se ha definido y es compatible con las matrices y la clase List<T>
:
IReadOnlyList<int> a = new[] {1, 2, 3, 4};
IReadOnlyList<int> b = new List<int> { 1, 2, 3, 4 };
Todavía no todo es perfecto porque la interfaz de lista mutable IList<T>
no hereda IReadOnlyList<T>
:
IList<int> c = new List<int> { 1, 2, 3, 4 };
IReadOnlyList<int> d = c; // error
Tal vez haya una posible compatibilidad con versiones anteriores con tal cambio.
Si hay algún progreso en cosas similares en las versiones más nuevas de Java, ¡me interesaría saber en los comentarios! :)
Las matrices pueden implementar interfaces ( Cloneable
y java.io.Serializable
). Entonces, ¿por qué no Iterable
? Supongo que las fuerzas de Iterable
agregan un método de iterator
, y las matrices no implementan métodos. char[]
ni siquiera anula toString
. De todos modos, las matrices de referencias deben considerarse menos que ideales: use List
s. Como comentarios de dfa, Arrays.asList
hará la conversión por ti, explícitamente.
(Dicho esto, puedes llamar a clone
en matrices).