Sử dụng đúng các tham số dòng lệnh Java -D


147

Khi truyền tham số -D trong Java, cách viết dòng lệnh thích hợp và sau đó truy cập nó từ mã là gì?

Ví dụ, tôi đã thử viết một cái gì đó như thế này ...

if (System.getProperty("test").equalsIgnoreCase("true"))
{
   //Do something
}

Và sau đó gọi nó như thế này ...

java -jar myApplication.jar -Dtest="true"

Nhưng tôi nhận được một NullPulumException. Tôi đang làm gì sai?


xem xét sử dụng compareToIgnoreCasethay vì equalsIgnoreCasecho định danh bất khả tri địa phương; nếu không, bạn có thể gặp phải vấn đề bốn-Is của Thổ Nhĩ Kỳ, trong số những vấn đề khác.
McDowell

4
Tôi có thể đề xuất sử dụng Boolean.getBoolean thay vì câu lệnh if dài mà bạn có không? shankh.com/2009/07/07/some-fun-with-boolean-getboolean
đánh dấu

-D là viết tắt của từ gì?
Anshul

Câu trả lời:


248

Tôi nghi ngờ vấn đề là bạn đã đặt "-D" sau sự -jar. Thử cái này:

java -Dtest="true" -jar myApplication.jar

Từ dòng lệnh giúp đỡ:

java [-options] -jar jarfile [args...]

Nói cách khác, cách bạn có được vào lúc này sẽ coi đó -Dtest="true"là một trong những lý lẽ để vượt quamain thay vì là đối số JVM.

(Bạn có lẽ cũng nên bỏ dấu ngoặc kép, nhưng dù sao nó cũng có thể hoạt động tốt - có lẽ nó phụ thuộc vào vỏ của bạn.)


14
Hoạt động hoàn hảo bây giờ. Một điều thú vị cần lưu ý là để sao chép hành vi này trong trình gỡ lỗi Eclipse, các loại tham số này phải được đặt trong phần Đối số VM trong phần Cấu hình chạy.
Ryan Berger

Ít nhất là từ bash nó hoạt động với các trích dẫn ở đó (và cũng cho phép khoảng trắng theo cách này), tôi sử dụng điều này cả ngày cho các cuộc gọi chống.
Paŭlo Ebermann

Cảm thấy thật ngu ngốc khi tôi dành bao nhiêu thời gian cho việc đó! Cảm ơn đã chỉ ra rằng. :)
toidiu

4
trong trường hợp ai đó thắc mắc, nếu bạn muốn vượt qua nhiều thuộc tính, chỉ cần sử dụng -D nhiều lần sau một 'khoảng trắng' java -D <key1> = <value1> -D <key2> = <value2> -D <key3> = <value3 > ...
p_champ

48

Đó phải là:

java -Dtest="true" -jar myApplication.jar

Sau đó, sau đây sẽ trả về giá trị:

System.getProperty("test");

Tuy nhiên, giá trị có thể là null, do đó, bảo vệ chống lại ngoại lệ bằng cách sử dụng Boolean:

boolean b = Boolean.parseBoolean( System.getProperty( "test" ) );

Lưu ý rằng getBooleanphương thức ủy nhiệm giá trị thuộc tính hệ thống, đơn giản hóa mã thành:

if( Boolean.getBoolean( "test" ) ) {
   // ...
}

1
bit cuối cùng cũng đúng với: Integer.getInteger("test"); Long.getLong("test")giả sử bạn có-Dtest=123
mt.uulu

23

Thay vào đó, bạn đang đưa ra các tham số cho chương trình của mình cho Java. Sử dụng

java -Dtest="true" -jar myApplication.jar 

thay thế.

Cân nhắc sử dụng

"true".equalsIgnoreCase(System.getProperty("test"))

để tránh NPE. Nhưng không sử dụng " điều kiện Yoda " luôn mà không suy nghĩ, đôi khi ném NPE là hành vi đúng đắn và đôi khi đại loại như

System.getProperty("test") == null || System.getProperty("test").equalsIgnoreCase("true")

là đúng (cung cấp mặc định đúng). Một khả năng ngắn hơn là

!"false".equalsIgnoreCase(System.getProperty("test"))

nhưng không sử dụng phủ định kép không làm cho nó bớt khó hiểu.


1
Trên thực tế, System.getProperty("test", "true").equalsIgnoreCase("true")sẽ là cách tốt hơn để viết điều kiện cuối cùng.
Paŭlo Ebermann

3
Boolean.getBoolean("test");là một lựa chọn khác. Xem .
superfav

@Paulo Giải pháp của bạn chỉ hoạt động cho các thuộc tính (tôi muốn hiển thị một tổng quát) nhưng đẹp hơn của tôi.
maaartinus

1
Thú vị: Trong câu trả lời này, tham số JVM xuất hiện sau cờ -jar, trong khi ở câu trả lời khác, nó xuất hiện sau "java" nhưng trước cờ -jar. Tôi lấy nó sau đó rằng khóa của họ chỉ là tham số JVM xuất hiện trước chính tệp JAR, trong trường hợp này là "myApplication.jar"?
Colm Bhandal

1
Thumbs up để chứng minh quan điểm về phủ định kép theo cách rõ ràng như vậy.
Silwing
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.