Java: metodi statici e non statici

noipo
Ciao a tutti,
non riesco a capire quando usare un metodo statico e quando uno non statico. Se voglio creare un metodo come faccio a sapere che questo è statico (o non statico)?
Ho carcato su internet e ho trovato un sacco di cose ma non mi è ancora chiaro perchè lo spiegano in maniera complicata. C'è qualcuno che gentilmente me lo potrebbe spiegare in maniera molto semplice? Ma molto molto (sono un pò ritardata :? )
Grazie! :)

Risposte
hamming_burst
Ciao,
"vfldj":
Ciao a tutti,
non riesco a capire quando usare un metodo statico e quando uno non statico. Se voglio creare un metodo come faccio a sapere che questo è statico (o non statico)?

bhe se è statico, ha prefissato la parola chiave static e questo è alla luce del sole...
il contrario, senza l'operatore "static", è "non statico"

il tuo dubbio è che non sai cosa sia un metodo statico? oppure non sai quando utilizzarlo?

PS: hai già dato un'occhiata qui?

(sono un pò ritardata :? )?

ahahaha w la sincerità :-D

noipo
Non capisco quando utilizzarlo :)

noipo
"hamming_burst":

PS: hai già dato un'occhiata qui?


Ho letto. Quello che ho capito è che i metodi statici vengono usati per accedere ai campi statici (come la get). Ma la differenza tra i metodi statici e non statici? :(

Perchè per esempio in questo programmino non posso usare dei metodi statici per incrementare e decrementare la variabile cont? Non è statica..
import java.util.Scanner;
public class Contatore {
	private int cont;

	public Contatore ()
		cont = 0;

	public Contatore (int cont) 
		this.cont = cont;

	public void init(int i) 
		cont = i;

	public int val() 
		return cont;

	public void incr() 
		cont++;

	public void decr() 
		cont--;
}



Oppure qui. Perchè i metodi nuovoConto e trovaConto non possono essere statici?
import java.util.Scanner;
public class Banca {
	Scanner tast = new Scanner(System.in);

	private ContoCorrente[] elencoConti;
	private int contatore = 0;

	public Banca(int lung) {
		elencoConti = new ContoCorrente[lung];

	public void nuovoConto(int saldo, String nome){
		if(contatore < elencoConti.length-1){
			ContoCorrente conto = new ContoCorrente(saldo, nome);
			elencoConti[contatore] = conto;
			contatore++;
	    }
	}

	public ContoCorrente trovaConto(int id){
		for(int i = 0; i < contatore; i++){
			if(id == elencoConti[i].getId())
			    return elencoConti[i];
		}
		return null;
	}
...
}


Grazie :)

hamming_burst
bhe la differenza intrinseca tra un metodo static ed uno non-static (oltre quello che hai detto), è che per utilizzarlo (il primo caso) non serve creare un'istanza (un oggetto) di una classe che ha proprio tale metodo.

Più chiaro? se no ne riparliamo :)

noipo
Riparliamone :-D

Ho appena iniziato a studiare Java quindi non faccio "quello che mi pare" ma seguo ciò che il prof mi dice quindi se lui mi chiede di scrivere un metodo che crei un nuovo conto (come nell'esempio di prima) io mi creo prima il metodo e poi lo provo con il main. Perciò prima penso al metodo e poi a provarlo e quindi a pensare se creare l'oggetto o no.
Non so se mi sono spiegata bene...
Il mio problema è appunto capire se un metodo lo devo fare static o no, poi a chiamarlo ci penso dopo..

Comunque grazie per la pazienza :D

hamming_burst
Ho appena iniziato a studiare Java quindi non faccio "quello che mi pare" ma seguo ciò che il prof mi dice quindi se lui mi chiede di scrivere un metodo che crei un nuovo conto (come nell'esempio di prima) io mi creo prima il metodo e poi lo provo con il main. Perciò prima penso al metodo e poi a provarlo e quindi a pensare se creare l'oggetto o no.
Non so se mi sono spiegata bene...

mi sembra accettabile :)

Il mio problema è appunto capire se un metodo lo devo fare static o no, poi a chiamarlo ci penso dopo..

i metodi/variabili static sono casi rari da creare, almeno negli esercizi. Te creali sempre non-static.

Però ho l'impressione che te non sai cosa comporti davvero essere una variabile statica.
Fai così: dimmi a parole cosa è per te una variabile static e cosa accade in memoria se dichiarata tale.

noipo
Una variabile statica è una variabile valida per tutta la classe.
In memoria succede che la variabile non sta nello stack ma in un'altra area.. mmmh

apatriarca
Partiamo per prima cosa dal vedere quali sono i principali usi di una variabile statica e poi passiamo ai metodi. Gli usi più comuni di una variabile statica sono:

1. Definire costanti o, più in generale, parametri globali per la classe o per l'intera applicazione. Un esempio sono le costanti Math.PI e Math.E nella classe Math. Ma queste costanti o parametri non devono per forza avere valori al di fuori della classe o dell'applicazione. Supponi per esempio di avere una classe Image che modella, come dice anche il nome, una immagine. In generale, un'immagine è caratterizzata da diverse caratteristiche come la sua dimensione, il formato dei singoli pixel (se è in bianco e nero o a colori, quanti bit ci sono per ogni colore, se un pixel può essere trasparente...), l'ordine con cui sono memorizzati i pixel, se ci sono dei byte aggiuntivi alla fine di ogni riga per motivi di allineamento dei dati, la compressione utilizzata.. Per gli usi più semplici, definire tutte le possibili impostazioni della classe potrebbe essere molto complesso e lungo. Si potrebbe allora per esempio decidere di avere dei valori di default per alcune di queste impostazioni e per non appesantire ogni classe con queste variabili si può decidere di renderle statiche (e possibilmente anche final). Un'alternativa potrebbe anche essere quella di definire una classe per gestire tutte le impostazioni e avere magari alcune "profili" memorizzati per usi particolari. Per esempio ci potrebbe essere un profilo "grayscale" per lavorare in scala di grigio, uno "HD720p" per un'immagine ad alta definizione a quella risoluzione e così via. Nota che i parametri globali di una classe non sono necessariamente costanti, ma si potrebbero avere dei modi per modificarli. E' però normalmente preferibile non avere tale possibilità o fare in modo che questi cambiamenti abbiano effetti solo sulle istanze create successivamente alla modifica.

2. Mantenere un qualche stato comune tra le diverse istanze della classe. Supponiamo che tu stia implementando una qualche classe che ha bisogno di eseguire spesso una qualche funzione molto costosa ma che sai che fornisce sempre lo stesso risultato fornendogli gli stessi valori di input. Se questi valori di input si ripetono spesso vale allora la pena di memorizzare questi valori da qualche parte in modo da poterli riutilizzare. Se è molto probabile che più istanze della classe calcolino gli stessi valori più volte diventa allora utile rendere i dati facilmente accessibili da tutte le istanze e quindi rendere questa struttura dati statica.

Ovviamente ci sono poi degli usi "intermedi" e forse anche altri usi che al momento non mi vengono in mente, ma credo che questi siano in generali i più comuni ed importanti. Per i metodi statici le cose non cambiano poi molto:

1. Funzioni matematiche o simili. In Java, per qualche assurda ragione, ogni metodo deve essere inserito in una qualche classe ma ci sono dei tipi che per ragioni di performance non sono classi. Si potrebbe infatti pensare che il metodo per il calcolo del seno appartenga al tipo sul quale operi (cioè float o double), ma questo non è possibile per cui si è reso necessario inserirle in qualche altra classe, Math in questo caso. In altri linguaggi, questa limitazione non esiste oppure esiste il concetto di funzione "libera" (nel senso non appartiene a nessuna classe - in effetti in alcuni linguaggi queste sono le uniche funzioni che esistono). Questo genere di funzioni non ha necessariamente a che fare con la matematica comunque, ci potrebbero essere altre ragioni per avere metodi che non apparterrebbero a nessuno. Per esempio potrebbero esserci funzioni che operano in modo simmetrico su diverse classi. Dove cioè non c'è alcuna classe che ha la prevalenza sulle altre e non è quindi certo a quale di queste classi dovrebbe appartenere. Se per esempio stessimo costruendo una qualche libreria geometrica che supporta diverse figure (come triangoli, quadrati, cerchi.. ) potremmo voler implementare un metodo per testare se due figure hanno intersezione non vuota o meno. E' però molto difficile decidere in quale classe inserire tale metodo. Dove inseriresti ad esempio un metodo per intersecare un quadrato e un cerchio? Nel cerchio? Nel quadrato? In una qualche classe genitore (se esiste)? Da qualche altra parte?

2. Modificare i parametri di una classe. Supponiamo per esempio che la nostra classe Image di prima abbia un parametro che definisce il colore di sfondo di default. Se volessimo creare tante immagini con un particolare colore di sfondo potremmo desiderare un qualche metodo statico per modificare questo valore di default. Oppure potrebbe avere un parametro per definire il formato del file di default con il quale vengono salvate le immagini e quindi un metodo statico per modificarlo.

3. Metodi di utilità. Ci sono a volte sequenze di istruzioni che si ripetono molte volte all'interno di una classe e ha quindi senso inserire tale metodo all'interno della classe. Di fatto, non ci sono particolari ragioni per cui questo genere di metodi vada statico, anzi a volte non è possibile renderlo statico, ma ci sono alcuni casi in cui ha più senso come metodo statico (per esempio nel caso in cui operi solo su variabili statiche della classe).

4. main. Il main deve per forza essere statico.

Probabilmente ci sono altri usi, ma credo che per ora questo post possa darti un'idea del perché uno possa desiderare un metodo di questo tipo. Nota che a volte un qualche programmatore potrebbe scegliere di implementare qualcosa usando quasi solo metodi statici per ragioni che vanno al di là di queste semplici osservazioni. Per esempio, se qualcuno volesse convertire un codice in C in cui non ci sono classi in Java, potrebbe almeno inizialmente seguire uno schema progettuale molto simile a quello seguito nel C e scrivere molti metodi statici per poi passare gradualmente ad un design più ad oggetti. E' in effetti perfettamente possibile scrivere un programma usando solo metodi statici o non usandoli affatto (escludendo quelli già presenti nelle librerie Java).

noipo
"apatriarca":
E' in effetti perfettamente possibile scrivere un programma usando solo metodi statici o non usandoli affatto (escludendo quelli già presenti nelle librerie Java).


Quindi alla fine scrivere metodi statici o non statici è "uguale" dato che un metodo statico si può scrivere come non statico e viceversa, giusto? :D

apatriarca
No, non necessariamente. E' però spesso modificare una classe o un programma in modo da rendere una funzione statica in non statica e viceversa.

noipo
Ok, grazie mille :D

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.