Hilo General - Dudas de Java

elkaoD

#120 pues busca sobre el tema y sorpréndete de cuantísimo hay que discutir xD

#120 pero en C además se permiten los pasos equivalente al ByRef de VB, cosa que en Java no.

¿La diferencia? Muy fácil:

void byReference(int& pointer) {
  *pointer += 10;
}

int whatever = 7;
int p_wahatever = &whatever;
byReference(&p_whatever);
printf("%d, "whatever);

RESULTADO: 17

A ver cómo haces eso en Java :P En Java sólo se soporta la indirección, pero no la manipulación de referencias (porque careces de operador de addressing & porque Java no te permite trabajar con el puntero directamente, no por otra cosa.)

4 respuestas
cabron

#121

Un detalle, aunque es un poco irrelevante. C no soporta referencias, fueron añadidas en C++, lo único que como C++ se diseño para ser compatible con C, la mayoría de compiladores te dejan mezclar cosas de C y C++ sin decir ni mu, por eso sin compilas eso en un archivo loquesea.c no te va a dar ningún error.

Si lo intentases compilar con un compilador que fuese de C puro, te daría error. En C para hacer eso, tienes que recurrir a punteros.

#123

No es por ser pesado... pero es que has hecho lo mismo que acabo de comentar

//Paso por punteros, válido en C y C++
int porPunteros(int* a, int* b)
{
	*a = *b;//Es necesario utilizar el operador de indirección
}

//Paso por referencias, válido en C++
int porReferencia(int& a, int& b)
{
	a = b; //No es necesario utilizar el operador de indirección
}

void main()
{
	int a,b,c,d;

porPunteros(&a,&b);//Hay que usar el operador de dirección
porReferencia(c,d);//No hay que usar el operador de dirección
}

2 respuestas
dagavi

Como creo que se está discutiendo aquí, efectivamente, Java solo pasar cosas por valor.

Sin embargo, que Java suela trabajar con punteros (todo menos tipos primitivos), hace confundir a la gente y hacerles creer que es un paso por referencia.

Yo pondría un ejemplo más simple aun, el típico que se suele dar, el intercambio de valores:

void swap(int& a, int& b) {
    int c = a;
    a = b;
    b = c;
}

Esto no se puede hacer con un paso por valor, puesto que "a" y "b" serían copias de lo pasado. En C se simula las referencias con punteros (lo que aun realiza más confusión cuando dices "en Java todo son punteros" y "en c se simula el paso por referencia con punteros" -> Java tiene paso por referencia).

Creo que ya traté también en este foro este tema.

Edit: Efectivamente, en este post: http://www.mediavida.com/foro/9/tratamiento-de-objetos-en-java-430214 (a partir de #9)
El ejemplo de "insertar(Nodo*& )" creo que es bueno ya que muestra un ejemplo de punteros pasados por referencia (algo que en Java, no se puede hacer, puesto que los argumentos son pasados por valor).

#121 Veo que acabaste por el buen camino xD

#122 No he leído los otros mensajes, simplemente he visto este hilo arriba y que se estaba comentando temas de paso por valor y referencia (como he dicho al principio), y siendo un hilo de Java he supuesto que se estaba discutiendo si Java hacía paso por valor o referencia.

No veo en que contradice mi mensaje al tuyo (a no ser que estuvierais hablando de C xD). Ya digo que "en C se simula las referencias con punteros", exactamente lo que tu indicas. C no tiene paso de argumentos por referencia, solo por valor. No he puesto en ningún momento C++, es cierto, pero la única referencia que realizo a C es para decir como se simulan.

3 respuestas
elkaoD

#122 #123 la historia es que en C se ha llamado paso por referencia a la indirección de toda la vida, por eso los que empezaron (empezamos) con C le llaman paso por referencia a lo de Java, y los de C++ NO le llaman paso por referencia.

Al menos así lo he visto en bibliografía antigua (allá cuando C no se aprendía por internet ;)) y por lo que comentan en StackOverflow no soy el único que ha visto esa nomenclatura (y de ahí la dicusión.)

Me parece absurdo discutir por nomenclatura porque creo que en el fondo simplemente es por falta de exactitud: todo el mundo intenta decir lo mismo con diferentes palabras xD De ahí #119 y lo de que me parece más adecuado "paso de referencia por valor".

1 respuesta
BLZKZ

y yo que pensaba que paso por valor es pasar el valor al que apunta el puntero, y por referencia es pasar la referencia del puntero..

xD

cabron

#124

No es cuestión de nomenclatura, yo también aprendí a programar con C mucho antes que C++ usando los términos por valor y por referencia, el comentario te lo he hecho por has puesto "Ejemplo en C", y luego has puesto:

void byReference(int& pointer)

Cuando tendría que ser:

void byReference(int* pointer)

Que a lo mejor ha sido por error nada más, pero si pones int& es C++, esa construcción no existe en C, pero vamos que ya puse que era un detalle irrelevante, ya que el fondo de la cuestión no cambia.

#123

Nada, es que pensaba que también estabas poniendo un ejemplo en C usando int&

2 respuestas
BLZKZ

#126 en c++ yo siempre llamo referencia constante a const int &, según vuestra teoria como se llama? xD

1 respuesta
elkaoD

#126 pues tienes razón, no sé si en alguno de los edits me lo cargaría o lo puse mal directamente.

Ya te digo que la nomenclatura que yo vi era así (y en SO hay gente que da la misma versión.) Que sea un error o una mala traducción no lo sé, pero se ha usado en literatura.

1 respuesta
dagavi

#127 Referencia constante. xD

#128 Es lo que tiene intentar enseñar paso por referencia en lenguajes que no tienen esa funcionalidad pero si la permiten simular (gracias a que puedes tratar con punteros). En el fondo, lo que estás haciendo realmente es implementar a bajo nivel el paso por referencia, ya que compilado no hará más que eso (modificar o obtener el contenido apuntado por la referencia que ha pasado).

B

#121: No entiendo qué me quieres decir con eso. Es decir, tienes toda la razón.

A lo que me refiero es que no es la primera vez que veo un súper debate sobre el tema de java y punteros, es muy sencillo: java manda un puntero al objeto. Punto xD. Si cambias el objeto, cambiará, si cambias el puntero al objeto, no.

Llámalo X, pero el objeto se pasa por referencia xD

#131: Referencia al objeto por valor del puntero. Ok, más concreto xD

1 respuesta
elkaoD

#130 se pasa la referencia por valor :) Con la nomenclatura del argumento contrario, pasar por referencia es cuando se pasa la dirección la variable que contiene el objeto, no el valor del puntero.

Eso en Java no es posible porque no existe el operador de direccionamiento &, así que sólo puedes pasar el valor de un puntero, no su dirección.

#130 es un detalle importante. En Java no puedes modificar el valor de una variable externa a tu scope porque no puedes direccionarla! Sólo puedes modificar tu stack local.

Como digo, yo a eso le he llamado siempre paso por referencia, y lo he visto mucho. No sé si es incorrecto o sólo es una nomenclatura más vieja, pero la discusión es sobre la semántica de la frase y no de lo que se quiere decir.

1 1 respuesta
dagavi

Decir que se pasa una referencia a un objeto no me parece incorrecto. De hecho es cierto. Es como si en C programas una función con punteros (recordemos que C no tiene argumentos por referencia), es correcto decir: pasamos una referencia a esta cosa.

Así que la frase " Llámalo X, pero el objeto se pasa por referencia xD" no me parece mal, efectivamente, el objeto es pasado por referencia, ahora bien, los parámetros de la función son parámetros por valor (que pasan una referencia a un objeto)

1
Y

Buenas tardes a ver si me podeis echar una mano. Estoy empezando con java y me apetecia pillarme una especie de enciclopedia de java(cuando empece con C++ me pille el deitel y deitel y me fue genial). Estoy dudando entre estos dos:

-http://www.casadellibro.com/libro-como-programar-en-java/9789702611905/1223777

-http://www.amazon.es/C%C3%B3mo-Programar-Java-Novena-Edicion/dp/6073211503/ref=sr_1_1?s=books&ie=UTF8&qid=1345453067&sr=1-1

Por lo que veo el libro de Amazon es mucho mas nuevo que el de casa del libro, lo que me extraña es que el nuevo solo tenga 616 paginas y el antiguo tenga 1200.......¿Cual os parece mejor?¿Cual me recomendais?

1 respuesta
Ronso

#133 Tengo este http://www.casadellibro.com/libro-como-programar-en-java/9789702611905/1223777 y te lo recomiendo, esta muy bien, del otro no puedo hablar. Eso sí al ser tan tochaco y venir en encuadernación de pasta "jode" un poco, por eso yo lo pille electrónico y lo imprimí a mi gusto para tenerlo en canutillo.

angelorz

Tengo una duda tonta y un poco bastante urgente :(

Tengo una interfaz llamada ContactoInterfaz, ¿ok?

Ahora, en otra clase diferente llamada Agenda.java hago lo siguiente:

public class Agenda implements AgendaInterfaz {
     private ContactoInterfaz matriz [] = null;
     (...)

 public Agenda (String archivo) throws OperacionNoPermitidaExcepcion {
      this.matriz = new ContactoInterfaz[MAX_NUM_CONTACTOS];
      (...)

La duda es la siguiente:

Sé que matriz se toma como una referencia a cualquier clase que implemente la interfaz ContactoInterfaz, pero lo que no comprendo es lo que quiere hacer debajo con el new ContactoInterfaz[MAX_NUM_INTERFAZ].

¿Es una tabla de referencias a partir de una referencia? ¿Algo así como que matriz es un "puntero a puntero" en C?

Es que me he comido la cabeza pensando que era una instancia de una interfaz, cosa que no se puede hacer (por eso del new, hasta que me he fijado que no son paréntesis sino corchetes lo que contiene a MAX_NUM_INTERFAZ) pero por lo que parece es una tabla de referencias.

En fin, tengo hecha la picha un lío, a ver si alguien me puede aclarar.

Gracias.

1 respuesta
Sergeon

Hombre yo lo que veo es que matriz es un nombre horroroso para esa variable.

Y luego, pues supongo que será un array de referencias a objetos de clases que implementen ContactoInterfaz, como dices. O sea, matriz[0] apuntará a algo (me imagino que a un contacto, obtenido gracias al archivo) que implemente ContactoInterfaz, etc.

No está intentando hacer un new ContactoInterfaz(), porque como dices es imposible, las interfaces solo admiten realizaciones parciales. Lo que hace es inicializar el array a un tamaño, exactamente igual que si haces int[] array = new int[10]; Si no usare el new en matriz no podría usarlo, y cualquier intento de usar matriz[n] te daría un nullPointerException.

1 1 respuesta
angelorz

#136 Viene así en el proyecto que tengo que hacer, así q así se va a quedar. Ya sé que el estilo/nombre es horroroso pero me interesa comprender qué hace xD La verdad es que ahora mismo el nombre para mí es lo de menos :)

O sea, que al contrario que al crear la referencia "matriz", lo que haces con el new es crear en memoria muchas más referencias, ¿no? (con "ContactoInterfaz matriz [] = null" no crearías hueco en memoria, ¿no? No es como si en "c" haces "int * p = NULL", que sí que se crea un hueco en memoria de tipo "int *").

Uy qué lío :) Aún así me estás aclarando bastante, gracias!

Sergeon

La verdad es que no te puedo asegurar qué pasa a bajo nivel, ni en la ram, cuando haces ContactoInterfaz = null. Lo que sí sé seguro es que si no haces un new o le asignas otro array del mismo tipo, siempre que luego intentes usar matriz[n] te va a saltar una excepción, no tengo muy claro así del tirón si de NullPointer o de IndexOutOfBounds, pero creo que una de las dos.

Esa línea lo único que hace es darle un length al array para poder usarlo, si no, no podrías.

1 1 respuesta
angelorz

#138 Creo que sería de NullPointer por tratar de acceder a memoria reservada por el sistema.

1
Lecherito

He leido esto: As with variables of other types, the declaration does not actually create an array — it simply tells the compiler that this variable will hold an array of the specified type.

Parece ser que solo le dice al compilador que esa variable va a tener un array nada más, luego cuando haces el new ContactoInterfaz[MAX_NUM_CONTACTOS]; es cuando la inicializas, aunque en un principio sean null los objetos, pero ya tienen su espacio en memoria y puedes cambiar su valor.

1 1 respuesta
angelorz

#140 Bueno, es que técnicamente no son objetos sino variables de instancia.

Si fueran objetos no podría hacerse porque no se pueden crear objetos de interfaces... ¿no? xD

Aún así me ha aclarado también eso :) Ya todo encaja poco a poco jajaja.

B

#135: Sencillamente está declarando que matriz (vaya forma más horrible de programar te han pasado, la verdad :palm: ) es un array donde se van a meter una serie de objetos de tipo "ContactoInterfaz" (en este caso que implementan esa interfaz). Si no haces eso, no tendrás esos huecos para colocar los objetos.

2
cabron

Vaya lío has hecho:

"No es como si en "c" haces "int * p = NULL", que sí que se crea un hueco en memoria de tipo "int *"

Si haces int p = NULL; tienes una variable de tipo int que no te vale de nada hasta que reserves el int con int p = malloc(sizeof(int)); o int p = new int; (en c++).

En C++ tienes dos opciones :

MiClase objeto;

MiClase* objeto;

La primera crea un objeto, la segunda no, por lo que la segunda necesita un:

MiClase* objeto = new Objeto();

Ahora por razones de la lógica del programa, puede que no crees el objeto hasta más tarde, vale, pero cual es la diferencia entre:

MiClase* objeto;

y

MiClase* objeto = nullptr;

Pues que si no inicalizas a null, el puntero apunta a un lugar indefinido, por ejemplo:

MiClase* objeto;

if (objeto)
{
objet->miMetodo() //Se la pega, no es null por lo que entra en el if, pero apunta vete a saber donde

}

MiClase* objeto = nullptr;

iif (objeto)
{
objet->miMetodo() //No entra en el if

}

Vale, ahora llevando esto a Java, mientras que en C++ podías hacer MiClase objeto; y MiClase* objeto, en java solo puedes hacer MiClase objeto; que equivale a MiClase* objeto; de C++, es decir, en java todo son punteros.

A diferencia de C++ donde tienes la opción de no inicializarlo a null (con el riesgo de a saber a donde apunta), en java no es necesario, las variables miembro se inicializan a null automáticamente, aunque si lo quieres poner de forma explícita no pasa nada:

class MiClase{

private MiOtraClase m_objeto;
private MiOtraClase m_objeto2 = null; //Es lo mismo
}

otro rollo son las variables dentro de un método, que no se inicializan a nada, pero a diferencia de C++ donde te dejan usarlas (aunque pete por que apunta a cuenca), en Java no puedes y tienes que explícitamente inicializarlas a null:

class MiClase{

private void miMetodo()
{
MiOtraClase objeto;
MiOtraClase objeto2 = null;

if(objeto2 != null) //Lo puedes hacer, por que objeto2 se inicializó a null

if(objeto != null) //Va a petar, por que objeto no está inicializado, de hecho creo que hasta peta en compilación

}
}

1 1 respuesta
angelorz

#143 Perfecto. Ahora lo entiendo xD

en java solo puedes hacer MiClase objeto; que equivale a MiClase* objeto; de C++, es decir, en java todo son punteros.

Pensaba que había que hacer distinción entre "tipos de puntero" (de orden superior etc) pero veo que no. Perfecto xD

Mil gracias a todos!! :)

1 mes después
Wasd

A ver, que debo de ser tonto o algo:

Si el valor máximo de un long es este: 9223372036854775807

1 respuesta
elkaoD

#145 ese literal es un entero a secas.

1 -> Integer
1L -> Long

Debes distinguir entre literal y tipo de variable.

2 1 respuesta
Wasd

#146 Joder, vaya chorrada.
Muchas gracias xD.

El caso es que hasta ahora los long los había utilizado para asignar valores incrementales en un bucle por ejemplo, pero nunca para asignar un valor directo a una variable al comienzo del programa.

En fin, gracias de nuevo y perdón por la chorrada.

9 días después
D4rk3viL

buenas, acabo de iniciarme en esto de la programación, llevo menos de una semana... y como comprenderéis tengo mil dudas a cada paso que doy y seguramente mil chorradas.... bueno el caso es que estaba mirando un ejercicio que se supone esta corregido y me han saltado varias dudas al respecto, y quería ver si alguien podría resolvermelas.

la primera es que el ejercicio te da 2 datos entre otros:
El valor de la variable totalfactura es 10350,677734
El valor de la variable totalfactura en notación científica es 1.035068E+04

y no se muy bien que hace con estos 2 datos por que la cifra que sale en el ejercicio es..
double totalfactura = 10350.677734; y no se ni como se lee la "notacion cientifica" ni que es E+04.. ni que hace o como hace con ellas para sacar ese ultimo dato.

Por otro lado en la linea 27 veo que al final pone + (float)totalfactura); que creo que ese float ahi, lo que esta haciendo es una conversión, pero lo que no se es por que y para que?

y para terminar los "%b","%d", "%.6f"..... que son y para que sirven..

el codigo es este

gracias

B

Up!

Alguien podría decirme como cargar una imagen de una base de datos (blob) y mostrarla en un jLabel sin usar Icon?

No se si esta bien, pero para meterla a la BD tengo esto:

File file = new File(path);
FileInputStream fis = new FileInputStream(file);
ps.setBinaryStream(5, fis, (int)file.length());
22 días después
deak0n

Buenas, mas que una duda voy a pedir un poco de ayuda por aquí y así no hace falta que cree un post que se contesta rápidamente.

Quiero aprender a programar en Java y me gustaría saber si conocéis alguna página web o recursos por internet donde pueda aprender desde cero hasta saber manejar relativamente bien/fácil Java.
Sé programar en C++ y espero que eso me ayude.

Y de paso, por si alguien se siente amable, lo mismo para PHP. ¿Conocéis alguan página web que te enseñe a programar en PHP?

Gracias de antemano.

2 respuestas
Tema cerrado