Domanda

La firma del metodo di un metodo Java main() è:

public static void main(String[] args){
    ...
}

C'è un motivo per cui questo metodo è statico?

È stato utile?

Soluzione

Il metodo è statico perché altrimenti ci sarebbe ambiguità: quale costruttore dovrebbe essere chiamato? Soprattutto se la tua classe si presenta così:

public class JavaClass{
  protected JavaClass(int x){}
  public void main(String[] args){
  }
}

La JVM dovrebbe chiamare new JavaClass (int) ? Cosa dovrebbe passare per x ?

In caso contrario, JVM dovrebbe istanziare JavaClass senza eseguire alcun metodo di costruzione? Penso che non dovrebbe, perché questo sarà un caso speciale per tutta la tua classe - a volte hai un'istanza che non è stata inizializzata e devi controllarla in ogni metodo che potrebbe essere chiamato.

Ci sono troppi casi limite e ambiguità perché abbia senso che la JVM debba istanziare una classe prima che venga chiamato il punto di ingresso. Ecco perché main è statico.

Non ho idea del perché main sia sempre contrassegnato public .

Altri suggerimenti

Questa è solo una convenzione. In effetti, anche il nome main () e gli argomenti passati sono puramente convenzionali.

Quando si esegue java.exe (o javaw.exe su Windows), ciò che sta realmente accadendo è un paio di chiamate Java Native Interface (JNI). Queste chiamate caricano la DLL che è in realtà la JVM (giusto - java.exe NON è la JVM). JNI è lo strumento che usiamo quando dobbiamo colmare il mondo delle macchine virtuali, e il mondo di C, C ++, ecc ... Il contrario è anche vero - non è possibile (almeno per quanto ne so) ottenere effettivamente un JVM in esecuzione senza utilizzare JNI.

Fondamentalmente, java.exe è un'applicazione C super semplice che analizza la riga di comando, crea un nuovo array String nella JVM per contenere tali argomenti, analizza il nome della classe specificato come contenente main (), utilizza le chiamate JNI per trovare il metodo main () stesso, quindi invoca il metodo main (), passando l'array di stringhe appena creato come parametro. Questo è molto, molto simile a quello che fai quando usi il riflesso da Java - usa invece chiamate di funzioni native con nome confuso.

Sarebbe perfettamente legale per te scrivere la tua versione di java.exe (il sorgente è distribuito con JDK) e fare in modo che qualcosa di completamente diverso. In effetti, è esattamente quello che facciamo con tutte le nostre app basate su Java.

Ognuna delle nostre app Java ha il suo launcher. Lo facciamo principalmente in modo da ottenere la nostra icona e il nome del processo, ma è tornato utile in altre situazioni in cui vogliamo fare qualcosa oltre alla normale chiamata main () per far andare le cose (ad esempio, in un caso che stiamo facendo Interoperabilità COM e in realtà passiamo un handle COM in main () anziché in una matrice di stringhe).

Quindi, lungo e corto: il motivo per cui è statico è il b / c che è conveniente. Il motivo per cui si chiama 'main' è che doveva essere qualcosa, e main () è quello che hanno fatto ai vecchi tempi di C (e in quei giorni, il nome della funzione era importante) . Suppongo che java.exe avrebbe potuto permetterti di specificare solo un nome di metodo principale completo, anziché solo la classe (java com.mycompany.Foo.someSpecialMain) - ma ciò rende più difficile agli IDE il rilevamento automatico di " classi "lavabili" in un progetto.

Il metodo main () in C ++ , C # e Java sono statici
Poiché possono quindi essere invocati dal motore di runtime senza senza dover istanziare alcun oggetto, il codice nel corpo di main () farà il resto.

Perché il vuoto statico pubblico principale (String [] args)?

Ecco come è progettato Java Language e Java Virtual Machine è progettato e scritto.

Specifica del linguaggio Oracle Java

Scopri Capitolo 12 Esecuzione - Sezione 12.1.4 Invoke Test.main :

  

Infine, dopo il completamento dell'inizializzazione per la classe Test (durante la quale potrebbero essersi verificati altri carichi, collegamenti e inizializzazioni consequenziali), viene invocato il metodo principale di Test.

     

Il metodo principale deve essere dichiarato pubblico, statico e nullo. Deve accettare un singolo argomento che è una matrice di stringhe. Questo metodo può essere dichiarato come

public static void main(String[] args)
     

o

public static void main(String... args)

Specifiche della macchina virtuale Java Oracle

Scopri Capitolo 2 Concetti relativi al linguaggio di programmazione Java - Sezione 2.17 esecuzione :

  

La macchina virtuale Java avvia l'esecuzione richiamando il metodo principale di una classe specificata e passandogli un singolo argomento, che è un array di stringhe. Questo fa sì che la classe specificata venga caricata (§2.17.2), collegata (§2.17.3) ad altri tipi che utilizza e inizializzata (§2.17.4). Il metodo principale deve essere dichiarato pubblico, statico e nullo.

Origine Oracle OpenJDK

Scarica ed estrai il jar di origine e guarda come viene scritta JVM, controlla ../launcher/java.c , che contiene il codice C nativo dietro il comando java [-options] class [args ...] :

/*
 * Get the application's main class.
 * ... ...
 */
if (jarfile != 0) {
    mainClassName = GetMainClassName(env, jarfile);

... ...

    mainClass = LoadClass(env, classname);
    if(mainClass == NULL) { /* exception occured */

... ...

/* Get the application's main method */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
                                   "([Ljava/lang/String;)V");

... ...

{    /* Make sure the main method is public */
    jint mods;
    jmethodID mid;
    jobject obj = (*env)->ToReflectedMethod(env, mainClass,
                                            mainID, JNI_TRUE);

... ...

/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
    ReportExceptionDescription(env);
    goto leave;
}

/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

... ...

Facciamo semplicemente finta che statico non sarebbe richiesto come punto di ingresso dell'applicazione.

Una classe di applicazione dovrebbe apparire così:

class MyApplication {
    public MyApplication(){
        // Some init code here
    }
    public void main(String[] args){
        // real application code here
    }
}

La distinzione tra codice costruttore e metodo principale è necessaria perché in OO un costruttore deve solo assicurarsi che un'istanza sia inizializzata . Dopo l'inizializzazione, l'istanza può essere utilizzata per il "servizio" previsto. Mettere l'intero codice dell'applicazione nel costruttore lo rovinerebbe.

Quindi questo approccio imporrebbe tre diversi contratti sull'applicazione:

  • deve essere un costruttore predefinito. Altrimenti, la JVM non saprebbe quale costruttore chiamare e quali parametri dovrebbero essere forniti.
  • deve essere un metodo principale 1 . Ok, questo non è sorprendente.
  • La classe non deve essere abstract . Altrimenti, la JVM non potrebbe istanziarla.

L'approccio statico invece richiede solo un contratto:

  • Deve esistere un metodo principale 1 .

Qui non è importante né abstract né costruttori multipli.

Poiché Java è stato progettato per essere un linguaggio semplice per l'utente non sorprende che anche il punto di ingresso dell'applicazione sia stato progettato in modo semplice usando il contratto e non in modo complesso usando tre contratti indipendenti e fragili.

Nota: questo argomento non è non sulla semplicità all'interno della JVM o all'interno della JRE. Questo argomento riguarda la semplicità per utente .


1 Qui la firma completa conta come un solo contratto.

In caso contrario, quale costruttore dovrebbe essere utilizzato se ce ne sono più di uno?

Sono disponibili ulteriori informazioni sull'inizializzazione e l'esecuzione dei programmi Java disponibili in Specifica del linguaggio Java .

Prima di chiamare il metodo principale, nessun oggetto viene istanziato. Avere la parola chiave statica significa che il metodo può essere chiamato senza prima creare alcun oggetto.

Perché altrimenti, avrebbe bisogno di un'istanza dell'oggetto per essere eseguita. Ma deve essere chiamato da zero, senza costruire prima l'oggetto, poiché di solito è compito della funzione main () (bootstrap), analizzare gli argomenti e costruire l'oggetto, di solito usando questi argomenti / parametri del programma.

Qual è il significato di public static void main (String args []) ?

  1. public è un identificatore di accesso che significa che chiunque può accedervi / invocarlo come JVM (Java Virtual Machine.
  2. static consente di chiamare main () prima che un oggetto della classe sia stato creato. Ciò è necessario perché main () viene chiamato da JVM prima che vengano creati oggetti. Poiché è statico, può essere richiamato direttamente tramite la classe.

    class demo {    
        private int length;
        private static int breadth;
        void output(){
            length=5;
            System.out.println(length);
        }
    
        static void staticOutput(){
            breadth=10; 
            System.out.println(breadth);
        }
    
        public static  void main(String args[]){
            demo d1=new demo();
            d1.output(); // Note here output() function is not static so here
            // we need to create object
            staticOutput(); // Note here staticOutput() function is  static so here
            // we needn't to create object Similar is the case with main
            /* Although:
            demo.staticOutput();  Works fine
            d1.staticOutput();  Works fine */
        }
    }
    

    Allo stesso modo, a volte usiamo statica per i metodi definiti dall'utente in modo da non dover creare oggetti.

  3. void indica che il metodo main () viene dichiarato non restituisce un valore.

  4. String [] args specifica l'unico parametro nel metodo main () .

    args - un parametro che contiene una matrice di oggetti di tipo classe String.

Lasciami spiegare queste cose in un modo molto più semplice:

public static void main(String args[])

Tutte le applicazioni Java, tranne le applet, iniziano la loro esecuzione da main () .

La parola chiave public è un modificatore di accesso che consente al membro di essere chiamato dall'esterno della classe.

static viene utilizzato perché consente di chiamare main () senza dover istanziare un'istanza specifica di quella classe.

void indica che main () non restituisce alcun valore.

Vengono costruite applet, midlet, servlet e bean di vario tipo e vengono quindi chiamati metodi del ciclo di vita. Invocare main è tutto ciò che viene mai fatto alla classe principale, quindi non è necessario che uno stato venga mantenuto in un oggetto chiamato più volte. È abbastanza normale aggiungere main a un'altra classe (anche se non è un'ottima idea), che potrebbe ostacolare l'utilizzo della classe per creare l'oggetto principale.

È solo una convenzione, ma probabilmente più conveniente dell'alternativa. Con un main statico, tutto ciò che devi sapere per invocare un programma Java è il nome e la posizione di una classe. Se non fosse statico, dovresti anche sapere come creare un'istanza di quella classe o richiedere che la classe abbia un costruttore vuoto.

Se il metodo principale non fosse statico, dovrai creare un oggetto della tua classe principale dall'esterno del programma. Come vorresti farlo?

Quando si esegue la Java Virtual Machine (JVM) con il comando java ,

java ClassName argument1 argument2 ...

Quando si esegue l'applicazione, si specifica il nome della sua classe come argomento per il comando java, come sopra

la JVM tenta di invocare il metodo principale della classe specificata

  

& # 8212; a questo punto, non sono stati creati oggetti della classe.

     

Dichiarando main come statico consente a la JVM di invocare main senza creando   un istanza della classe.

torniamo al comando

ClassName è un argomento della riga di comando per la JVM che indica quale classe eseguire. Seguendo il ClassName, puoi anche specificare un elenco di stringhe (separato da spazi) come argomenti della riga di comando che la JVM passerà alla tua applicazione. -Questi argomenti potrebbero essere usati per specificare le opzioni (ad es. Un nome file) per eseguire l'applicazione- questo è il motivo per cui esiste un parametro chiamato String [] args nella schermata principale

Riferimenti: Java & # 8482; Come programmare (Early Objects), decima edizione

Penso che la parola chiave 'statico' trasformi il metodo principale in un metodo di classe e che i metodi di classe ne abbiano una sola copia e possano essere condivisi da tutti, inoltre non richiede un oggetto come riferimento. Pertanto, quando viene compilata la classe del driver, è possibile richiamare il metodo principale. (Sono solo a livello alfabetico di Java, scusami se sbaglio)

main () è statico perché; a quel punto del ciclo di vita dell'applicazione, lo stack dell'applicazione è di natura procedurale a causa dell'assenza di oggetti ancora istanziati.

È una lavagna pulita. La tua applicazione è in esecuzione a questo punto, anche senza alcun oggetto dichiarato (ricorda, ci sono schemi di codifica procedurale E OO). Tu, come sviluppatore, trasformi l'applicazione in una soluzione orientata agli oggetti creando istanze dei tuoi oggetti e in base al codice compilato all'interno.

Orientato agli oggetti è ottimo per milioni di ovvi motivi. Tuttavia, sono passati i giorni in cui la maggior parte degli sviluppatori di VB utilizzava regolarmente parole chiave come " goto " nel loro codice. & Quot; goto " è un comando procedurale in VB che viene sostituito dalla sua controparte OO: invocazione del metodo.

Potresti anche considerare il punto di ingresso statico (principale) come pura libertà. Se Java fosse stato abbastanza diverso da creare un'istanza di un oggetto e presentarti solo quell'istanza in esecuzione, non avresti scelta MAI scrivere un'app procedurale. Per quanto inimmaginabile possa sembrare per Java, è possibile che ci siano molti scenari che richiedono approcci procedurali.

Questa è probabilmente una risposta molto oscura. Ricorda, " class " è solo una raccolta di codice correlato. & Quot; grado " è una generazione autonoma isolata, vivente e che respira di quella classe.

Il protoipo public static void main (String []) è una convenzione definita in JLS :

  

Il metodo principale deve essere dichiarato pubblico, statico e nullo. Deve specificare un parametro formale (& # 167; 8.4.1) il cui tipo dichiarato è array di String.

Nella specifica JVM 5.2. Avvio della macchina virtuale possiamo leggere:

  

La macchina virtuale Java si avvia creando una classe iniziale, che viene specificata in modo dipendente dall'implementazione, usando il caricatore di classi bootstrap (& # 167; 5.3.1). La macchina virtuale Java collega quindi la classe iniziale, la inizializza e invoca il metodo della classe pubblica void main (String []) . L'invocazione di questo metodo guida tutte le ulteriori esecuzioni. L'esecuzione delle istruzioni della macchina virtuale Java che costituisce il metodo principale può causare il collegamento (e di conseguenza la creazione) di classi e interfacce aggiuntive, nonché l'invocazione di metodi aggiuntivi.

Cosa divertente, nelle specifiche JVM non si dice che il metodo principale debba essere statico. Ma la specifica dice anche che la macchina virtuale Java esegue 2 passaggi prima:

  

L'inizializzazione di una classe o interfaccia consiste nell'eseguire la sua classe o il suo metodo di inizializzazione dell'interfaccia.

In 2.9. Metodi speciali :

È stata definita una classe o metodo di inizializzazione dell'interfaccia :

  

Una classe o un'interfaccia ha al massimo una classe o un metodo di inizializzazione dell'interfaccia e viene inizializzata (& # 167; 5.5) invocando quel metodo. Il metodo di inizializzazione di una classe o interfaccia ha il nome speciale < clinit > , non accetta argomenti ed è nullo.

E un metodo di inizializzazione di classe o interfaccia è diverso da un metodo di inizializzazione dell'istanza definito come segue:

  

A livello della macchina virtuale Java, ogni costruttore scritto nel linguaggio di programmazione Java (JLS & # 167; 8.8) appare come un metodo di inizializzazione dell'istanza che ha il nome speciale < init > .

Quindi la JVM inizializza una classe o metodo di inizializzazione dell'interfaccia e non un metodo di inizializzazione dell'istanza che in realtà è un costruttore. Quindi non è necessario menzionare che il metodo principale deve essere statico nelle specifiche JVM perché è implicito dal fatto che nessuna istanza viene creata prima di chiamare il metodo principale.

Di recente, una domanda simile è stata pubblicata su Programmers.SE

  • Perché un metodo principale statico in Java e C #, piuttosto che un costruttore?
      

    Alla ricerca di una risposta definitiva da una fonte primaria o secondaria perché (in particolare) Java e C # hanno deciso di avere un metodo statico come punto di ingresso & # 8211; piuttosto che rappresentare un'istanza dell'applicazione da un'istanza di una classe Application , con il punto di ingresso un costruttore appropriato?

TL; DR parte della risposta accettata è,

  

In Java, la ragione di public static void main (String [] args) è che

     
      
  1. Gosling voleva
  2.   
  3. il codice scritto da qualcuno con esperienza in C (non in Java)
  4.   
  5. deve essere eseguito da qualcuno abituato a eseguire PostScript su NeWS
  6.   
     
    

 http://i.stack.imgur.com/qcmzP.png

  
     

& nbsp;
  Per C #, il ragionamento è transitivamente simile per così dire. I progettisti linguistici hanno mantenuto il entry point del programma sintassi familiare per programmatori provenienti da Java. Come architetto C # Anders Hejlsberg lo mette ,

     
    

... il nostro approccio con C # è stato semplicemente quello di offrire un'alternativa ... ai programmatori Java ...

  
     

...

È solo una convenzione. La JVM potrebbe certamente affrontare i metodi principali non statici se quella fosse stata la convenzione. Dopotutto, puoi definire un inizializzatore statico sulla tua classe e creare un'istanza di un milione di oggetti prima di arrivare al tuo metodo main ().

La parola chiave public è un modificatore di accesso, che consente al programmatore di controllare la visibilità dei membri della classe. Quando un membro della classe è preceduto da public , allora quello al membro è possibile accedere tramite codice esterno alla classe in cui è dichiarato.

Il contrario di public è private , che impedisce a un membro di essere utilizzato da un codice definito al di fuori della sua classe.

In questo caso, main () deve essere dichiarato come public , poiché deve essere chiamato per codice al di fuori della sua classe all'avvio del programma.

La parola chiave statico consente main () da chiamare senza dover creare un'istanza di una particolare istanza della classe. Ciò è necessario poiché main () viene chiamato dall'interprete Java prima che vengano creati oggetti.

La parola chiave void indica semplicemente al compilatore che main () non restituisce un valore.

Il vero punto di accesso a qualsiasi applicazione è un metodo statico. Se il linguaggio Java supportava un metodo di istanza come "punto di ingresso", il runtime avrebbe bisogno di implementarlo internamente come metodo statico che costruiva un'istanza dell'oggetto seguita chiamando il metodo di istanza.

Detto questo, esaminerò la logica per la scelta di una delle tre opzioni seguenti:

  1. Un static void main () come lo vediamo oggi.
  2. Un metodo di istanza void main () ha chiamato un oggetto appena costruito.
  3. Usando il costruttore di un tipo come punto di ingresso (ad esempio, se la classe di ingresso fosse chiamata Program , l'esecuzione sarebbe effettivamente costituita da new Program () ) .

Breakdown:

static void main ()

  1. Chiama il costruttore statico della classe che racchiude.
  2. Chiama il metodo statico main () .

void main ()

  1. Chiama il costruttore statico della classe che racchiude.
  2. Crea un'istanza della classe che racchiude chiamando in modo efficace new ClassName () .
  3. Chiama il metodo dell'istanza main () .

new ClassName ()

  1. Chiama il costruttore statico della classe che racchiude.
  2. Costruisce un'istanza della classe (quindi non fa nulla con essa e semplicemente restituisce).

Motivazione:

Vado in ordine inverso per questo.

Tieni presente che uno degli obiettivi di progettazione di Java era enfatizzare (se possibile) buone pratiche di programmazione orientate agli oggetti. In questo contesto, il costruttore di un oggetto inizializza l'oggetto, ma non dovrebbe essere responsabile del comportamento dell'oggetto. Pertanto, una specifica che ha fornito un punto di ingresso di new ClassName () confonderebbe la situazione per i nuovi sviluppatori Java forzando un'eccezione alla progettazione di un "ideale" costruttore su ogni applicazione.

Rendendo main () un metodo di istanza, il problema sopra è sicuramente risolto. Tuttavia, crea complessità richiedendo alla specifica di elencare la firma del costruttore della classe di immissione e la firma del metodo main () .

In breve, specificando un static void main () si crea una specifica con la minima complessità aderendo al principio di mettere il comportamento nei metodi . Considerando quanto sia semplice implementare un metodo main () che costruisce esso stesso un'istanza di una classe e chiama un metodo di istanza, non vi è alcun vantaggio reale nel specificare main () come metodo di istanza.

statico - Quando la JVM effettua una chiamata al metodo principale non esiste alcun oggetto per la classe chiamata, pertanto deve disporre di un metodo statico per consentire l'invocazione dalla classe.

Non so se JVM chiama il metodo principale prima che gli oggetti vengano istanziati ... Ma c'è un motivo molto più potente per cui il metodo main () è statico ... Quando JVM chiama il metodo principale del classe (diciamo, Persona). lo invoca da " Person.main () " ;. Vedete, la JVM lo invoca con il nome della classe. Questo è il motivo per cui il metodo main () dovrebbe essere statico e pubblico in modo che sia accessibile dalla JVM.

Spero che abbia aiutato. In caso affermativo, fammi sapere commentando.

I metodi statici non richiedono alcun oggetto. Funziona direttamente, quindi il main funziona direttamente.

La parola chiave statica nel metodo principale viene utilizzata perché non è presente alcuna istanza nel metodo principale. Ma l'oggetto è costruito piuttosto che invocazione, di conseguenza usiamo la parola chiave statica nel metodo principale. Nel contesto jvm la memoria viene creata quando la classe viene caricata in essa e tutti i membri statici sono presenti in quella memoria. se rendiamo lo statico principale ora sarà in memoria e sarà accessibile a jvm (class.main (..)) in modo da poter chiamare il metodo principale senza la necessità di creare heap.

È solo una convenzione, come possiamo vedere qui:

  

Il metodo deve essere dichiarato pubblico e statico , non deve restituire alcun metodo   valore e deve accettare un array String come parametro. Di default,   il primo argomento non opzionale è il nome della classe da invocare.   È necessario utilizzare un nome di classe completo. Se l'opzione -jar è   specificato, il primo argomento non opzionale è il nome di un archivio JAR   contenente file di classe e di risorse per l'applicazione, con il   classe di avvio indicata dall'intestazione manifest di classe principale.

http://docs.oracle. com / JavaSE / 1.4.2 / docs / tooldocs / windows / java.html # descrizione

  

Le parole chiave del vuoto statico pubblico indicano che l'interprete della macchina virtuale Java (JVM) può chiamare il metodo principale del programma per avviare il programma (pubblico) senza creare un'istanza della classe (statico) e il programma non restituisce dati all'interprete Java VM (vuoto) al termine.

Fonte: Essentials, Part 1, Lesson 2: Building Applications

Fondamentalmente creiamo quei MEMBRI DATI e FUNZIONI MEMBRI come STATICI che non stanno eseguendo alcuna attività relativa ad un oggetto. E nel caso del metodo principale, lo stiamo realizzando come STATICO perché non ha nulla a che fare con l'oggetto, poiché il metodo principale viene sempre eseguito indipendentemente dal fatto che si stia creando o meno un oggetto.

Qualsiasi metodo dichiarato come statico in Java appartiene alla classe stessa. Anche in questo caso è possibile accedere al metodo statico di una determinata classe solo facendo riferimento alla classe come Class_name.method_name();

Quindi non è necessario creare un'istanza di una classe prima di accedere a un metodo statico.

Quindi il metodo main () è dichiarato come statico in modo che sia possibile accedervi senza creare un oggetto di quella classe.

Poiché salviamo il programma con il nome della classe in cui è presente il metodo principale (o da dove il programma dovrebbe iniziare la sua esecuzione, applicabile per le classi senza un metodo main () () ( Livello avanzato)). Quindi, nel modo sopra menzionato:

Class_name.method_name();

è possibile accedere al metodo principale.

In breve quando il programma viene compilato cerca il metodo main () con argomenti String come: main (String args []) nella classe menzionata (ovvero con il nome del programma) e poiché all'inizio non ha spazio per creare un'istanza di quella classe, quindi il metodo main () è dichiarato statico.

Da java.sun.com (ci sono ulteriori informazioni sul sito):

  

Il metodo principale è statico per fornire all'interprete Java VM un modo per avviare la classe senza creare prima un'istanza della classe di controllo. Le istanze della classe di controllo vengono create nel metodo principale dopo l'avvio del programma.

La mia comprensione è sempre stata semplicemente che il metodo principale, come qualsiasi metodo statico, può essere chiamato senza creare un'istanza della classe associata, consentendone l'esecuzione prima di qualsiasi altra cosa nel programma. Se non fosse statico, dovresti creare un'istanza di un oggetto prima di chiamarlo, il che crea un problema "pollo e uovo", poiché il metodo principale è generalmente quello che usi per creare un'istanza di oggetti all'inizio del programma.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top