2011-12-22 20 views
42

Tôi đã được hỏi câu hỏi này trong một cuộc phỏng vấn.In thư trên Bảng điều khiển mà không cần sử dụng phương thức main()

Cách in thư trên bảng điều khiển mà không cần sử dụng phương thức main()?

+3

Làm thế nào bạn sẽ bắt đầu bạn ứng dụng mà không có một phương pháp chính? – RoflcoptrException

+14

Tôi không thể xem đây là câu hỏi phỏng vấn hay. Chắc chắn bạn muốn kiểm tra khả năng giải quyết vấn đề của người nộp đơn, không phải là kiến ​​thức về các khía cạnh ít được sử dụng của Java? –

+14

@CallumRogers +1 trivia là loại câu hỏi tồi tệ nhất, bất cứ ai hỏi những câu hỏi đó không xứng đáng là sếp của tôi. –

Trả lời

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

Chương trình System.exit(0) thoát trước khi JVM bắt đầu tìm kiếm main()

Ideone link

(Lưu ý: ngay cả khi nó biên dịch với JDK 7 javac nó không thể chạy với java của nó, bởi vì nó mong đợi phương thức main(String[]).)

+1

@Roflcoptr '$ java Foo' giống như bất kỳ –

+1

@Roflcoptr' java -cp khác. Foo' giống như một chương trình với chính. ;) –

+0

@Roflcoptr chỉ biên dịch lớp và chạy 'java Foo' nó sẽ tải lớp, in thư; và chúng ta thoát ra trước khi nó bắt đầu tìm thấy điểm vào để thực thi. –

10

Trong tệp có tên A.java

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

Bạn chỉ cần biên dịch chương trình trên Windows. Không chạy nó. :-P

+2

Điều này hoạt động vì 'CON' có ý nghĩa đặc biệt trên Windows, phải không? –

+3

Điều này cũng in toàn bộ rất nhiều các chất liệu khác quá. "Con" bằng cách nào? Nó không cho phép đặt tên tệp là "Con.java". +1. –

+10

-1 Cung cấp giải pháp cụ thể cho nền tảng cho vấn đề trong ngôn ngữ độc lập nền tảng không chính xác. –

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

    } 
} 

Vì khối khởi tạo tĩnh được thực hiện khi lớp được tải lần đầu tiên, chúng tôi có thể in “Hello World” mà không cần viết phương thức chính. Việc thực hiện được dừng lại bằng cách sử dụng lệnh “System.exit()”. Vì vậy, chúng tôi ngăn chặn lỗi "phương pháp chính không tìm thấy". Đó là khá một câu hỏi khó

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

Khối tĩnh là lần đầu tiên thực hiện càng sớm càng lớp được nạp trước khi phương pháp main(); được gọi và do đó trước khi main() được gọi, System.exit(0) khởi VM đóng cửa.

Phương pháp System.exit tạm dừng việc thực hiện chuỗi hiện tại và tất cả những người khác đã chết trong tuyến đường của họ. Khi System.exit được gọi, máy ảo thực hiện hai tác vụ dọn dẹp trước khi tắt.

Đầu tiên, nó thực thi tất cả các móc tắt đã được đăng ký với Runtime.addShutdownHook. Điều này rất hữu ích để giải phóng tài nguyên bên ngoài VM. Sử dụng móc tắt cho hành vi phải xảy ra trước khi VM thoát.

Nhiệm vụ dọn dẹp thứ hai do VM thực hiện khi System.exit được gọi là mối quan tâm cuối cùng. Nếu một trong hai số System.runFinalizersOnExit hoặc số điện thoại độc ác Runtime.runFinalizersOnExit của chúng tôi đã được gọi, máy ảo sẽ chạy finalizers trên tất cả các đối tượng chưa được hoàn tất. Các phương pháp này đã không còn được sử dụng trong thời gian dài trước đây và với lý do chính đáng. Không bao giờ gọi System.runFinalizersOnExit hoặc Runtime.runFinalizersOnExit vì bất kỳ lý do nào: Chúng nằm trong số các phương thức nguy hiểm nhất trong các thư viện Java. Gọi các phương thức này có thể dẫn đến finalizers đang chạy trên các đối tượng trực tiếp trong khi các thread khác đồng thời thao tác chúng, dẫn đến hành vi thất thường hoặc bế tắc.

Tóm lại, System.exit dừng tất cả các chuỗi chương trình ngay lập tức; nó không gây ra các khối cuối cùng để thực thi, nhưng nó chạy các móc tắt máy trước khi tạm dừng máy ảo. Sử dụng móc tắt máy để chấm dứt tài nguyên bên ngoài khi máy ảo tắt .Có thể dừng máy ảo mà không thực thi móc tắt bằng cách gọi System.halt, nhưng phương pháp này hiếm khi được sử dụng.

6

Bạn có thể định nghĩa một bộ nạp lớp tùy chỉnh mà in thông điệp của bạn:

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

Sau đó chạy lệnh java:

java -Djava.system.class.loader=MyClassLoader

(không cần phải thêm một lớp như tham số)

1

Có, một trong những cách là khối tĩnh nhưng trong phiên bản trước đó của JDK không có trong JDK 1.7.

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

Output: Nội dung: Thông điệp của bạn có thể được in trên giao diện điều khiển mà không cần phương pháp main() (nếu không muốn nói JDK7)

Output: Lỗi: phương thức Main không tìm thấy trong lớp A3, xin vui lòng xác định phương pháp chính như : public static void main (string [] args)

Reference

2

Đó là có thể đến java 6 để sử dụng System.out.println(); không có chính(). Từ java 7 trở đi, không thể làm điều đó với khối tĩnh. Nó vẫn sẽ yêu cầu phương pháp chính trong lớp chính.

+0

vâng tôi đã thấy ở nhiều nơi, nhưng tôi không rõ tại sao không thực hiện trong phiên bản jdk7 và phiên bản mới hơn, nếu bạn có thể cung cấp thêm chi tiết về điều này sẽ rất tuyệt. –

2

Nếu bạn không muốn sử dụng khối tĩnh quá, nó có thể được thực hiện sau cách

public class NoMain { 

    private static final int STATUS = getStatus(); 

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

} 

Tuy nhiên, xin lưu ý rằng đây là dành cho Java 6 phiên bản. not working in Java 7 của nó được cho là được hỗ trợ trong Java 8. Tôi đã thử với JDK 1.8.0_77-b03, mà vẫn không hoạt động

0

Thực ra nó không hoạt động trong bản cập nhật mới nhất của java 8. Bạn có thể gọi nó là sửa lỗi theo họ, nhưng theo như tôi tin vào kiến ​​thức hiện tại của tôi điều này không thể được gọi là sửa lỗi vì nó cũng dẫn đến vài thay đổi khái niệm quá trong lập trình java.

0

Có, bạn có thể in thư tới bảng điều khiển mà không cần sử dụng main().

Tạo một thử nghiệm với JUnit và thực hiện nó:

@Test 
public printTest() { 
    System.out.println("myprint"); 
} 
Các vấn đề liên quan