2012-04-05 46 views
13

Gần đây tôi đã được hỏi trong bài kiểm tra nếu định dạng public static void main(String arg[]) của phương thức main đã được sửa chưa? Chúng ta có thể thay đổi nó không? Chúng tôi có thể sử dụng main mà không cần bất kỳ public, static hoặc void không? Nếu không, tại sao nó không được mã hóa cứng rằng main(String arg[]) sẽ đứng cho public static void main(String arg[]) luôn?public static void main (String arg []) trong java là nó cố định?

Trả lời

22

Chữ ký của phương pháp chính được quy định trong Java Language Specifications section 12.1.4 và nêu rõ:

The method main must be declared public, static, and void. It must specify a formal parameter (§8.4.1) whose declared type is array of String.

  • nó phải public nếu không nó sẽ không thể gọi nó là
  • nó phải static vì bạn không có cách nào để khởi tạo một đối tượng trước khi gọi nó là
  • danh sách các đối số String ở đó để cho phép chuyển các tham số khi thực thi một chương trình Java từ dòng lệnh. Nó sẽ có thể xác định nó mà không có đối số nhưng thực tế hơn như vậy (và tương tự như các ngôn ngữ khác)
  • kiểu trả về là void vì nó không có ý nghĩa gì khác: một chương trình Java có thể chấm dứt trước khi tiếp cận kết thúc phương thức chính (ví dụ, Bằng cách gọi System.exit())

Chữ ký phương pháp do đó có thể là:

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

lưu ý rằng varargs phiên bản (...) chỉ có giá trị từ Java 5

Khi ngôn ngữ Java cho phép các dấu ngoặc đơn [] được định vị sau loại hoặc biến (thường được ưu tiên),

public static void main(String args[]) // valid but usually non recommended 

cũng là hợp lệ

+0

Bạn có thể dễ dàng tạo một trình khởi chạy mới sẽ thực hiện theo cách khác, phương thức này không phải là công khai (giao diện JNI cho phép bạn gọi ** bất kỳ phương thức ** nào) và không cần phải là tĩnh , giao diện JNI một lần nữa có thể tạo ** đối tượng bất kỳ ** bằng cách gọi hàm khởi tạo của nó và sau đó gọi phương thức cá thể. –

+3

@ MaurícioLinhares Tôi hoàn toàn biết rằng tôi có thể gọi bất cứ điều gì tôi muốn nhưng không có đảm bảo rằng nó sẽ làm việc. Một JVM (có JVM khác cũng không phải từ Oracle) chỉ bị buộc phải tuân thủ các thông số kỹ thuật. Họ có thể chỉ đơn giản là tạo ra một lỗi và nói với bạn "không có cách nào, không tiêu chuẩn ngay cả khi về mặt kỹ thuật có thể". Một đặc điểm kỹ thuật được gọi là đặc điểm kỹ thuật cho một lý do. – Matteo

+0

** không đảm bảo rằng nó sẽ hoạt động **? Ý bạn là như thế nào? Đó là phóng cá nhân của tôi sẽ không hoạt động vì spec nói khác? Bất kỳ trình chạy ** nào cũng hoạt động ** miễn là lớp được khởi chạy đáp ứng tiêu chí của nó, vui lòng kiểm tra các câu trả lời khác và các ví dụ về mã nguồn. –

0

Phương thức chính phải là public để JVM có thể tìm thấy nó khi lớp được tải. Tương tự, nó phải là static để nó có thể được gọi sau khi tải lớp, mà không cần phải tạo một thể hiện của nó. Tất cả các phương thức phải có kiểu trả về, trong trường hợp này là void.

+0

vì vậy chúng tôi có thể có loại trả lại không trống? I am new to java – amar

+0

@amar không có nó bị vô hiệu vì nó được xác định như vậy trong đặc tả ngôn ngữ – Matteo

0

Tôi không thể trả lời cho các đối số của phương thức nhưng nó phải được công khai vì jvm phải có khả năng truy cập chức năng và phải tĩnh vì jvm không biết cách tạo một thể hiện của lớp của bạn.

bài này cung cấp một câu trả lời chi tiết tốt về lý luận cho tĩnh: Why is the Java main method static?

bài này cung cấp một câu trả lời tốt cho lý do tại sao chính là khoảng trống: Why is main() in java void?

-2

Bạn có thể thay đổi nó nếu bạn tạo một bộ nạp mới cho ứng dụng của bạn. public void void chính (String args []) định dạng chỉ là giải pháp mặc định người làm việc trên JVM tìm thấy để gọi các chương trình Java của bạn, để có một xác định cách để làm điều đó.

Việc thực hiện thực chúng ta có ngày hôm nay chỉ sử dụng giao diện JNI để gọi public static void main (args String []) phương pháp bằng cách sử dụng this function, vì vậy bạn có thể dễ dàng viết chính xác cùng mã nếu bạn muốn sử dụng JNI và có một phương pháp khác để tải ứng dụng của bạn.

Here's an example in code được lấy từ this page.

Đây là chương trình trình khởi chạy Linux hiện tại, the method lookup starts here.

+0

Bạn chắc chắn? Mã nguồn của điểm phát sóng của tôi có mã nguồn cứng: '(* env) -> GetStaticMethodID (env, mainClass," chính ", " ([Ljava/lang/String;) V "); ' – Voo

+0

Không có nó được xác định trong thông số ngôn ngữ và nó chỉ được đảm bảo hoạt động nếu được thực hiện như được định nghĩa. Bất cứ điều gì không theo các thông số kỹ thuật không được đảm bảo để hoạt động. http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1.4 – Matteo

+0

Tất nhiên, hãy kiểm tra mã nguồn trình khởi chạy. https://gist.github.com/2310831#L465 –

2

Nếu bạn nhìn vào mã JDK nguồn (jdk-src \ J2SE \ src \ share \ bin \ java.c):

/* Get the application's main method */ 
mainID = (*env)->GetStaticMethodID(env, mainClass, "main", 
        "([Ljava/lang/String;)V"); 
... 
{ /* Make sure the main method is public */ 
... 
mods = (*env)->CallIntMethod(env, obj, mid); 
if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */ 
    message = "Main method not public."; 
    messageDest = JNI_TRUE; 
    goto leave; 
... 

Nó trở nên rất rõ ràng rằng nó phải chỉ có chữ ký này.

+3

Tôi đồng ý nhưng mã JDK không phải là tài liệu tham khảo chính xác. Các thông số ngôn ngữ là – Matteo

+1

Việc triển khai thông số không phải là tham chiếu chính xác? Cái này thổi tôi lên. –

+9

Không * thực hiện * một đặc điểm kỹ thuật không phải là một tham chiếu. Thậm chí có thể sai. Không có * triển khai *. Chỉ có * một * thực hiện. – Matteo

-2
  • công main() phương pháp phải được sử dụng bởi bất kỳ một trong những bên ngoài lớp cũng như bên trong lớp nên công

  • tĩnh tĩnh của nó là cần thiết bcoz trong java nếu chúng ta định nghĩa lớp chúng tôi xác định đối tượng cho lớp đó và hơn và chỉ hơn chúng tôi có thể sử dụng lớp đó..nhưng thay vì điều này chúng tôi trực tiếp sử dụng bằng cách viết từ tĩnh

  • void-for main() không thể trả về bất kỳ giá trị nào như int hoặc char main() - main là hàm hoặc phương thức mà chúng ta có thể sử dụng để truy cập tương lai của java String-trong java tất cả chúng ta viết xem xét như là một chuỗi args-luận

0

If not, why is it not hard coded that main(String arg[]) would stand for public static void main(String arg[]) always?

Bạn có thể có phương pháp gọi là "chính" với bất kỳ chữ ký và truy cập bạn muốn. Các quy tắc đặc biệt chỉ áp dụng cho phương thức bạn muốn JVM gọi để bắt đầu một chương trình.

public class Test { 
    public static void main(String[] args) { 
    StrangeMain m = new StrangeMain(); 
    System.out.println(m.main()); 
    System.out.println(m.main(new String[]{"aaa","bbb"})); 
    } 
} 

class StrangeMain{ 
    protected String main(){ 
    return "xyzzy"; 
    } 
    protected String main(String[] arg){ 
    return arg[0]; 
    } 
} 

biên dịch, chạy, và kết quả đầu ra:

xyzzy 
aaa 
1

Công là một loại truy cập specifier do đó chúng ta có thể truy cập nó từ bên ngoài lớp học. Vì chính là hàm hoạt động như một điểm thực thi. Hàm main được gọi bởi JVM nằm ngoài lớp, vì vậy nó phải được khai báo là public.

Tĩnh là một loại từ khóa được sử dụng trong java để chỉ định rằng không cần phải tạo bất kỳ phiên bản nào của từ khóa đó. Như chúng ta biết phương thức chính cũng nằm bên trong một lớp và để truy cập chức năng cụ thể của một lớp từ bên ngoài lớp (Trong trường hợp này từ JVM), một cá thể của lớp đó là cần thiết, để tránh chúng ta chỉ cần đặt tĩnh để tạo truy cập phương thức chính bên ngoài lớp.

Void là kiểu trả về vì kiểu trả về khác trong phương thức chính là vô nghĩa.

Chuỗi là tên lớp được xác định trước trong java. Và args [] là một biến kiểu mảng. Đó là tên biến của đối tượng Kiểu chuỗi. Vì vậy, chúng ta cũng có thể thay đổi tên của args []. Lớp chuỗi và đối tượng của nó có thể được truyền trong một chương trình đang chạy làm đối số để truyền thông tin đến phương thức chính từ dòng lệnh.

0
   Public static void main(String [] ar) 

Để hiểu điều này, chúng ta cần biết cú pháp của phương thức và mảng.

Cú pháp của phương pháp là:

kiểu trả methodName

nên phương pháp chính được viết cùng với khoảng trống đó là kiểu trả về.

Cú pháp của mảng:

datatype [] arrayName

các dấu ngoặc vuông chỉ ra cho dù đó là của mảng chiều Kể từ khi chúng tôi có một cặp vuông niềng răng nó là một mảng kích thước.

Ý nghĩa của từ trong phương thức main:

công cộng: Công là sự xác định quyền truy cập nó là dành cho mục đích của JVM để thực hiện phương pháp chính từ bất kỳ địa điểm.

Tĩnh: Tĩnh là công cụ sửa đổi. Phương thức chính phải được khai báo là tĩnh để JVM có thể truy cập trực tiếp phương thức chính bằng cách sử dụng tên lớp.

Khi chúng tôi thực hiện chương trình java, chúng tôi sử dụng tên lớp để khi viết tĩnh, nó sẽ giúp JVM truy cập vào phương thức chính.

Nếu chúng ta loại bỏ tĩnh thì nó trở thành phương thức thể hiện, để truy cập một phương thức thể hiện chúng ta nên tạo và đối tượng và sau đó gọi phương thức bằng cách sử dụng tham chiếu đối tượng.

void: Void là kiểu trả về của phương thức chính. Người gọi của phương thức chính là JVM và JVM không mong đợi bất kỳ giá trị nào từ phương thức chính và có phương thức chính không trả về bất kỳ giá trị nào. Đây là lý do để chỉ định Void.

chính: Chính là tên phương thức và được cố định theo quy ước mã hóa Java.

Chuỗi []: Nó được sử dụng để lưu trữ đối số dòng lệnh. Tên của mảng có thể là bất kỳ số nhận dạng Java hợp lệ nào.

Vì vậy, sau chuỗi [] chúng tôi có thể đặt tên như bất kỳ số nhận dạng java hợp lệ nào có thể là 'ar' hoặc nó có thể là 'args'.

Các vấn đề liên quan