2011-12-22 13 views
42

Zostałem zadany to pytanie w wywiadzie.Drukowanie wiadomości na konsoli bez użycia metody głównej()

Jak wydrukować wiadomość na konsoli bez użycia metody main()?

+3

Jak zacząć jesteś aplikacja bez głównej metody? – RoflcoptrException

+14

Nie widzę tego jako dobrego pytania do wywiadu. Na pewno chcesz przetestować zdolność rozwiązywania problemów wnioskodawcy, a nie znajomość mało używanych aspektów Java? –

+14

@CallumRogers +1 ciekawostki to najgorszy rodzaj pytań, każdy, kto zadaje te pytania, nie zasługuje na to, aby być moim szefem. –

Odpowiedz

62
public class Foo { 
    static { 
     System.out.println("Message"); 
     System.exit(0); 
    } 
} 

Program System.exit(0) wyjścia przed JVM zaczyna szukać main()

Ideone link

(Uwaga: nawet jeśli kompiluje z JDK 7 na javac nie można uruchomić z jego java, bo spodziewa się metody main(String[]).)

+1

@Roflcoptr '$ java Foo' tak jak każdy inny –

+1

@Roflcoptr' java -cp. Foo "jak program z głównym. ;) –

+0

@Roflcoptr po prostu skompiluj klasę i uruchom 'java Foo' załaduje klasę, wydrukuje wiadomość; i wychodzimy zanim zacznie on znajdować punkt wejścia do wykonania. –

10

W pliku o nazwie A.java

class Con { 
    String hi = "\n\nHello World\n\n"; 
} 

Trzeba tylko skompilować program w systemie Windows. Nie uruchamiaj go. :-P

+2

Działa to, ponieważ 'CON' ma specjalne znaczenie w systemie Windows, prawda? –

+3

To również drukuje wiele innych rzeczy. Czym jest "Con"? Nie pozwala nazwać pliku jako "Con.java". +1. –

+10

-1 Zapewnienie specyficznego dla platformy rozwiązania problemu w języku niezależnym od platformy jest nieprawidłowe. –

6
class MainMethodNot 
{ 
    static 
    { 
     System.out.println("Hello World"); 
     System.exit(0); 

    } 
} 

Ponieważ statyczny blok inicjująca jest wykonywana, gdy klasa jest najpierw załadowane, możemy wydrukować „Hello World” bez pisania główne metody. Wykonanie jest zatrzymywane przy użyciu polecenia "System.exit()". Dlatego zapobiegamy błędowi "główna metoda nie została znaleziona". Jest to dość trudne pytanie

12
public final class Main { 
    static { 
     System.out.println("Hello World"); 
     System.exit(0); 
    } 
} 

Statyczny blok jest najpierw wykonywany tak szybko, jak klasa jest ładowany zanim metoda main(); jest wywoływany, a zatem przed main() nazywa, System.exit(0) inicjuje VM zamknięty.

Metoda System.exit zatrzymuje wykonanie bieżącego wątku, a pozostałe martwe w swoich ścieżkach. Po wywołaniu System.exit maszyna wirtualna wykonuje dwa zadania czyszczenia przed zamknięciem.

Najpierw wykonuje wszystkie haki zamknięcia, które zostały zarejestrowane w Runtime.addShutdownHook. Jest to przydatne do udostępniania zasobów zewnętrznych na VM. Użyj haków zamknięcia dla zachowania, które musi wystąpić przed wyjściem z maszyny wirtualnej.

Drugie zadanie czyszczenia wykonywane przez maszynę wirtualną, gdy System.exit nazywa się , dotyczy finalizatorów. Jeśli zostanie wywołane System.runFinalizersOnExit lub jego złego bliźniaka Runtime.runFinalizersOnExit, VM uruchomi finalizatory na wszystkich obiektach, które nie zostały jeszcze sfinalizowane. Metody te zostały wycofane z długiego okresu wcześniej i nie bez powodu. Nigdy nie wywołuj z żadnego powodu: System.runFinalizersOnExit lub Runtime.runFinalizersOnExit: Są to jedne z najbardziej niebezpiecznych metod w bibliotekach Java. Wywołanie tych metod może spowodować, że finalizatory będą uruchamiane na żywych obiektach, podczas gdy inne wątki będą je jednocześnie manipulować, powodując nieprawidłowe zachowanie lub zakleszczenie.

Podsumowując, System.exit zatrzymuje natychmiast wszystkie wątki programu; nie powoduje to ostatecznie, że bloki są wykonywane, ale uruchamia haki wyłączające przed zatrzymaniem maszyny wirtualnej . Użyj haków zamykających, aby zakończyć zasoby zewnętrzne, gdy maszyna wirtualna zostanie wyłączona.Możliwe jest zatrzymanie maszyny wirtualnej bez wykonywania haków zamknięcia przez wywołanie System.halt, ale ta metoda jest rzadko używana.

6

Można zdefiniować niestandardowy ładujący klasy, która drukuje swoją wiadomość:

public class MyClassLoader extends ClassLoader { 
    public MyClassLoader(ClassLoader other) { 
     super(other); 
     System.out.println("Hi there"); 
     System.exit(0); 
    } 
} 

następnie uruchom polecenie Java:

java -Djava.system.class.loader=MyClassLoader

(nie trzeba dodać klasę jako parametr)

1

Tak, jednym ze sposobów jest blok statyczny, ale w poprzedniej wersji JDK nie w JDK 1.7.

class Withoutmain{ 
static{ 
    System.out.println("Message: Your message can be print on console without main() method"); 
    System.exit(0); 
} 
} 

wyjściowa: Wiadomość: Komunikat może być drukowanie na konsoli bez metody main() (jeśli nie JDK7)

wyjściowe: Błąd: Metoda Main Nie znaleziono w klasie A3, należy określić główną metodę jako : public static void main (String [] args)

Reference

2

było to możliwe do Java 6 używać System.out.println(); bez głównej(). Od wersji Java 7 nie można tego zrobić za pomocą bloku statycznego. Będzie nadal wymagać głównej metody w głównej klasie.

+0

Tak, widziałem w wielu miejscach, ale nie jestem pewien, dlaczego nie wykonać w jdk7 i późniejszej wersji, jeśli możesz podać więcej szczegółów na ten temat, byłoby świetnie. –

2

Jeśli nie chcesz używać zbyt statyczny blok, można to zrobić w następujący sposób

public class NoMain { 

    private static final int STATUS = getStatus(); 

    private static int getStatus() { 
     System.out.println("Hello World!!"); 
     System.exit(0); 
     return 0; 
    } 

} 

Należy jednak pamiętać, że jest to dla Java 6 wersji. Jest to not working in Java 7, który jest obsługiwany w języku Java 8. Próbowałem z JDK 1.8.0_77-b03, który nadal nie działa

0

W rzeczywistości nie działa w najnowszej aktualizacji java 8. Można go nazwać Naprawiono błąd zgodnie z nimi, ale o ile wierzę w moją aktualną wiedzę, nie można tego nazwać naprawą błędu, ponieważ doprowadziło to również do kilku zmian koncepcyjnych w programowaniu java.

0

Tak, możesz wydrukować wiadomość na konsoli bez użycia funkcji main().

Tworzenie test z JUnit i wykonać go:

@Test 
public printTest() { 
    System.out.println("myprint"); 
} 
Powiązane problemy