Buscar
Social
Ofertas laborales ES

Foro sobre Java SE > Duda con los campos static

OK cuando vi este codigo en el libro (Piensa en Java de Bruce Eckel) me surgio una duda, me costo un poco ver que cuando creas un objeto static se crea primero que los que no se crean con static. Mientras copiaba el codigo me daba error porque habia escrito las clases dentro del main. Y luego pense, porque igual me da error?, como funcionan los campos static?,Cual es la diferencia de una clase dentro del main y otra fuera del main?

package learning;

class bow1{
bow1(int marker){
System.out.println("bow1(" + marker + ")");
}
void f1(int marker){
System.out.println("f1("+ marker +")");
}
}
class table{
static bow1 bow13=new bow1(1);
table(){
System.out.println("table()");
bow12.f1(1);
}
void f2(int marker){
System.out.println("f2(" + marker + ")");
}
static bow1 bow12=new bow1(2);
}
class cupboard{
bow1 bow13=new bow1(3);
static bow1 bow14=new bow1(4);
cupboard(){
System.out.println("cupboard");
bow14.f1(2);
}
void f3(int marker){
System.out.println("f3(" + marker + ")");
}
static bow1 bow15=new bow1(5);
}
public class Duda_2 {
public static void main(String[] args){
System.out.println("Creating new cupboard in main");
new cupboard();
System.out.println("Creating new cupboard in main");
new cupboard();
table.f2(1);
cupboard.f3(1);
}
static table table=new table();
static cupboard cupboard=new cupboard();
}

agosto 1, 2015 | Registered Commentersaal

Hola, por lo general, a mi no me gusta escribir clases anidadas unas dentro de otras. Prefiero crear dos ficheros diferente una para cada clase, ya que el anidar clases a mi me resulta desordenado, aun así como estas haciendo un curso, esta bien que las veas, pero no me centraría mucho en eso, cuando cojas un poco de soltura, generalmente crearas una clase por archivo. Y esto es referente a tu segunda pregunta, pero ojo no es una clase dentro del main o fuera de este, es una clase dentro de otra clase, o crear un archivo por cada clase.
La ventaja que tiene es la posibilidad que una clase B contenida dentro de una clase A, solo es visible e instanciable en la clase A. Pero sinceramente, yo no lo uso mucho, por no decir nada. y tampoco lo he practicado mucho como para saber las implicaciones que tiene.

Después sobre el tema de los static, tanto los métodos, como los atributos, la diferencia entre otros métodos o atributos que no lo son, esta en la necesidad de crear un objeto o no tener que crearlo para poder acceder a el(atributo) o poder llamarlo(método).

Sean 3 clases:
Clase matematicas, tiene un atributo estatico(pi) y un metodo estatico(sumar(a,b)).

public class Matematicas{
public static double pi=3.141592;
public static int sumar(int a,int b){
return a+b;
}
}

Clase Persona tiene un atributo no estático(nombre) y un metodo no estatico(mostrarNombre())

public class Persona{
public String nombre;

public void mostrarNombre(){
System.out.println(nombre);
}
}

Clase principal donde haremos uso de las dos anteriores, con un metodo main

public static void main(String[] arg){
//usando la clase matematicas
System.out.println(Matematicas.pi);
System.out.println(Matematicas.sumar(5,7));

//usando la clase Persona
Persona p=new Persona();
p.nombre="pepe";
p.mostrarNombre();

}

Ahora si te fijas en la clase principal, para llamar a los elementos de la clase Matematicas, lo hemos echo a través del nombre de la clase, y no nos ha sido necesario crear un objeto de la clase Matematicas porque sus atributos y métodos son estáticos.

En cambio, para llamar al atributo nombre y el método mostrarNombre de la clase persona, previamente tuvimos que crear un objeto de la clase persona usando el operador new, y una vez tuvimos el objeto creado, llamamos a sus métodos y atributos a través de este objeto y no con el nombre de la clase como ocurría en el caso de los estáticos.

Por otro lado, la clase con los métodos y atributos estáticos, siempre sera igual, osea, pi siempre valdrá 3.14... y el método sumar siempre hará lo mismo, este es el significado de estático, que no cambia.

En cambio, en la clase con los elementos no estáticos, los métodos realizaran unas cosas u otras dependiendo del valor de los atributos, este caso es muy simple, pero a la persona. Pero por ejemplo en nuestra clase principal podríamos haber creado otro objeto Persona y haberle puesto otro nombre, y ya tendríamos dos objetos Persona cada uno con un nombre... En cambio en la de Matematicas el pi siempre tendrá el mismo valor.

Bueno espero que esto te aclare un poco en lugar de liarte mas, jaja. Practica y ya no entiendes algo o lo que sea, por aquí andaremos. Un saludo

agosto 1, 2015 | Registered Commenterloderain

Muchas gracias loderain.!!

agosto 2, 2015 | Unregistered Commentersaal

Los objetos static se crean "antes" porque se crean con la clase (o sea, cuando la JVM lee la clase, sin que sea necesario que se instancie ningún objeto concreto de ella). Si tienes una clase llamada Pepe, puedes hacer esto:


public class Pepe {
public static int pepeStatus = 0;
private int variableInstancia;

// get y set
}

y usarlo así:

Pepe.pepeStatus++;

Pepe pepito = new Pepe();
pepito.setVariableInstancia(3);
System.out.println(Pepe.pepeStatus); // imprime "1"
System.out.println(pepito.getVariableInstancie()); // imprime "3"

Pero no deberías (o ni siquiera podrías) hacer esto:


pepito.pepeStatus++; // Invocar una variable estática desde un objeto de instancia
Pepe.getVariableInstancia(); // Invocar una variable de instancia desde la clase

Para que te sea más fácil entenderlo, seguro que algo como java.awt.event.KeyEvent.VK_DELETE te suena natural ("la constante que identifica la tecla Suprimir"). Bueno, pues realmente eso es una variable estática como la de mi ejemplo, excepto que se ha declarado "final", por lo que no es posible modificar su valor una vez asignado (como parte de la definición de la clase), convirtiéndola en constante.

Sobre las clases anidadas, hay motivos legítimos para crearlas (incluso clases anidadas estáticas) y a veces quedan mejor organizadas, pero hay que encontrar los escenarios apropiados (y también puede ser un poco cuestión de gustos). Tengo que corregir a loderain, porque las clases anidadas pueden ser públicas (p.e.: JComboBox.KeySelectionManager), pero tienen sus detallitos para entenderlas bien.

En general, si quieres una clase anidada pública, seguramente será realmente una clase estática pública anidada, para que se pueda instanciar a partir de la clase principal; si no, al no ser estática, solo existe en las instancias de la clase principal. La diferencia es esta:


ClaseAnidada ca = new ClasePrincipal.ClaseAnidada(); // ClaseAnidada es estática pública
ClasePrincipal cp = new ClasePrincipal();
ClaseInstanciaAnidada cia = new cp.ClaseInstanciaAnidada(); // ClaseInstanciaAnidada es pública, pero no estática

El tutorial de Java de Oracle lo explica bastante bien.

agosto 4, 2015 | Registered Commenterrickiees

Holaaa, gracias por la corrección rikiees, jeje como comente, yo Huyo de clases anidadas, prefiero crearlas independientes, y la verdad que eso como dije, apenas las practique, ees una espinita que tengo ahí... Cualquier día de estos con tiempos y ganas me pongo para ver las implicaciones que conllevan, jeje.

Bueno y de nuevo gracias, es agradable saber que alguien lee los post ;) Un saludo.

agosto 5, 2015 | Registered Commenterloderain

La verdad es que no es que sean fundamentales (a efectos de organización, seguramente cualquier clase pública anidada también se podría crear de manera independiente y no afectaría a la legibilidad del programa) y según escribo esto estoy pensando que quizá compliquen las cosas a la hora de documentar en UML.

Y, sí, por supuesto que se lee, últimamente veo que contestas mucho, muchas gracias porque siempre es bueno que el foro tenga actividad (doy las gracias como un usuario más del foro que soy). :-)

agosto 6, 2015 | Registered Commenterrickiees