Tại sao Java không đặt tên tệp trong args?


20

Trong C và C ++, phương thức chính giữ tên tệp ở vị trí đầu tiên của mảng tại argv [0]. Tuy nhiên, trong Java, tên tệp không được bao gồm trong mảng chuỗi args.

Có một lý do thực tế cho việc này? Tôi hiểu rằng điều này làm cho việc lặp qua các đối số dòng lệnh dựa trên 0 thay vì dựa trên 1, nhưng có lợi ích gì không? Có phải tên tệp chỉ được coi là vô dụng?

Câu trả lời:


17

Trong một số trường hợp, một chương trình có thể được chạy theo những cách khác nhau và thể hiện hành vi khác nhau về cách nó được gọi. Nếu bạn gọi vimnhư vi, nó chạy trong một chế độ tương thích. Đôi khi, đó là cố gắng duy trì một phiên bản của một số chương trình liên quan - ví dụ mailqnewaliasestrên nhiều hệ thống unix là một liên kết để sendmailcác chương trình này được đồng bộ hóa)


Các chương trình Java thường được gọi là:

% java -jar foo.jar lập luận
% java Foo lập luận

Phiên bản đầu tiên là nơi bạn có tệp Manifest chỉ ra lớp chính, phiên bản thứ hai chạy phương thức chính trong lớp Foođược tìm thấy trong đường dẫn lớp.

Thông tin được trình bày cho Java là một đường dẫn đến tệp jar hoặc tên của lớp được gọi.

Vị trí của bình không đủ quan trọng để trở thành thứ gì đó để mã hóa (và thực tế không phải là một phần của thông số ban đầu). Một Jar có thể được đặt tên bất cứ thứ gì thực sự, và thường bao gồm số phiên bản. Hơn nữa, không có gì đảm bảo rằng lớp thậm chí được lưu trữ trong một .jar (nó có thể đã được trích xuất).

Gọi một ứng dụng Java -jarchỉ có một cách để nhập nó - lớp được định nghĩa trong Bản kê khai. Không có đổi tên có thể được thực hiện.

Tùy chọn khác, gọi nó với tên lớp chỉ trực tiếp đến đơn vị thực thi. Furthemore, nó không thể được đặt tên nhiều lần - bạn không Bar.classthể là mã cho class Foonó chỉ không hoạt động theo cách đó.

Điều này sẽ cho thấy rằng thực sự không có điểm nào để chuyển thông tin argv[0]theo nghĩa C cho ứng dụng Java - nó sẽ javavô nghĩa và tùy tiện hoặc tên của lớp đang được gọi (rằng bạn đang thực thi mã của (bạn có thể làm điều gì đó giống như getClass().getEnclosingClass().getName()nếu bạn tuyệt vọng ...)).

Có một điểm ở đây, bạn có thể định nghĩa nhiều phương thức chính trong các lớp trong một .jar hoặc trên đường dẫn lớp. Và bạn có thể khiến chúng cư xử khác đi giống như có một loạt các câu lệnh if dựa trên những gì argv[0]đã được.

Trước đây tôi có mã giống như java -cp Foo.jar com.me.foo.Testđã gọi Testphương thức Main của lớp chứ không phải là phương thức được định nghĩa trong phương thức được xác định trong Bản kê khai.


Phải có nhiều hơn thế. Trong C #, các tham số không chứa tên tệp, nhưng ứng dụng thường được thực thi trực tiếp, chỉ foo.exe.
Svick

@svick Tôi không quen thuộc với C #, cũng như cách exe được đóng gói. Trong một vài hệ điều hành, bạn có thể tạo một tệp thực thi jar (xem phần này ) để khởi chạy điểm nhập cảnh được xác định trong Bản kê khai. Những điều tương tự có thể được thực hiện cho C #. Điều quan trọng là bạn không thể thay đổi điểm vào bằng cách thay đổi tên của tệp và tên tệp không được sử dụng cho bất kỳ phần nào khác của ứng dụng (bên ngoài trình tải lớp).

@nqzero ( bối cảnh ) - Nếu tôi chỉ định java com.me.Foolàm dòng lệnh, phương thức com.me.Foo.main(String...)đang được gọi. Không có cách nào xung quanh đó. Và tôi biết rằng đó là Foo đang được viện dẫn - không có lý do gì để dính vào điều đó trong argv. Nó sẽ hoàn toàn là thông tin dư thừa. Chắc chắn, nó có thể nằm trong siêu lớp, nhưng tôi có cơ hội tầm thường để chặn nó với thông tin mong muốn về việc gọi dòng lệnh là gì - không cần phải đưa nó vào argv.

... Và hãy nhớ lấy 50 rep và bình luận thay vì gợi ý chỉnh sửa cho câu trả lời. Đó là một cách rất kém để nêu vấn đề với một bài đăng nhất định.

Đôi khi hành vi hoàn toàn khác nhau. ví dụ như wput thực sự là wget.
mckenzm

-4

thực sự không có lợi ích gì với nó, nó thực sự phụ thuộc vào cú pháp của ngôn ngữ lập trình bạn đang sử dụng nếu nó dựa trên 0 hoặc dựa trên 1. biến (bạn gọi là tên tệp) cũng phụ thuộc vào ngôn ngữ, nó có thể khác với các ngôn ngữ khác chỉ cần làm theo đúng cú pháp của ngôn ngữ bạn đang sử dụng.


1
Làm thế nào để trả lời câu hỏi này?
gnat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.