Làm thế nào để truy cập các lớp java trong gói mặc định?


98

Bây giờ tôi đang làm việc cùng với những người khác trong một dự án grails. Tôi phải viết một số lớp Java. Nhưng tôi cần quyền truy cập vào một đối tượng có thể tìm kiếm được tạo bằng groovy. Có vẻ như đối tượng này phải được đặt trong gói mặc định.

Câu hỏi của tôi là: Có cách nào để truy cập đối tượng này trong gói mặc định từ một lớp Java trong một gói được đặt tên không?

Câu trả lời:


129

Bạn không thể sử dụng các lớp trong gói mặc định từ một gói đã đặt tên.
( Về mặt kỹ thuật, bạn có thể, như được hiển thị trong câu trả lời của Sharique Abdullah thông qua API phản chiếu, nhưng các lớp từ không gian tên chưa được đặt tên không nằm trong phạm vi trong khai báo nhập )

Trước J2SE 1.4, bạn có thể nhập các lớp từ gói mặc định bằng cú pháp như sau:

import Unfinished;

Điều đó không còn được phép nữa . Vì vậy, để truy cập một lớp gói mặc định từ bên trong một lớp được đóng gói, yêu cầu chuyển lớp gói mặc định thành một gói của riêng nó.

Nếu bạn có quyền truy cập vào nguồn được tạo bởi groovy, thì cần phải xử lý hậu kỳ để chuyển tệp vào một gói chuyên dụng và thêm chỉ thị "gói" này vào đầu.


Cập nhật 2014: lỗi 6975015 , cho JDK7 và JDK8, mô tả một lệnh cấm thậm chí nghiêm ngặt hơn đối với việc nhập từ gói không có tên.

Tên TypeNamephải là tên chuẩn của một loại lớp, loại giao diện, loại enum hoặc loại chú thích.
Các loại phải là thành viên của một gói có tên , hoặc một thành viên của một loại mà ngoài cùng lexically kèm theo loại là thành viên của một gói có tên , hoặc một thời gian biên dịch lỗi xảy ra .


Andreas chỉ ra trong các bình luận :

"tại sao [gói mặc định] lại ở đó ngay từ đầu? lỗi thiết kế?"

Không, đó là cố ý.
JLS 7.4.2. Gói không tên cho biết: "Các gói không tên được cung cấp bởi nền tảng Java SE chủ yếu để thuận tiện khi phát triển các ứng dụng nhỏ hoặc tạm thời hoặc khi mới bắt đầu phát triển".


7
Như tôi đã giải thích với những người khác trước đây, gói mặc định là công dân hạng hai trong thế giới Java. Đừng làm vậy. :-)
Chris Jester-Young

1
Có vẻ như tôi phải học Groovy (trong một dự án rất hạn chế về thời gian) hoặc mã trong gói mặc định. :-(
Mnementh

11
@ ChrisJester-Young nếu vậy thì tại sao nó lại ở đó ngay từ đầu? lỗi thiết kế?
Pacerier

Tại sao nó không được dùng nữa?
Suzan Cioc

@SuzanCioc ý bạn là: "tại sao sau J2SE1.4, bạn không thể truy cập gói mặc định nữa?"
VonC

61

Trong thực tế, bạn có thể.

Sử dụng API phản xạ, bạn có thể truy cập bất kỳ lớp nào cho đến nay. Ít nhất tôi đã có thể :)

Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");

Đối với Scala, mã sau đây hoạt động:val bar = "hi"; val fooClass = Class.forName("FooClass"); val fooMethod = fooClass.getMethod("foo", classOf[Array[String]]); val fooReturned = fooMethod.invoke(fooClass.newInstance(), Array(bar));
Jus 12

2
Câu trả lời tuyệt vời, +1. Kể từ khi câu hỏi được groovy, tuy nhiên, bạn có thể sử dụng gõ vịt (như ống taping tôi đoán) ...Class.forName("FooBar").newInstance().fooMethod("I did it")
Bill K

7

Sử dụng jarjar để đóng gói lại tệp jar với quy tắc sau:

rule * <target package name>.@1

Tất cả các lớp trong gói mặc định của tệp jar nguồn sẽ di chuyển đến gói đích, do đó có thể truy cập.


4
một bản demo về cách sử dụng Jarjar sẽ là tuyệt vời
BiGGZ

@BiGGZ: Xem README.md file trên Jarjar github repo để xem làm thế nào để sử dụng Jarjar với ant, gradle hoặc dòng lệnh.
Lucidiot

3

Bạn có thể sử dụng các gói trong Groovymã và mọi thứ sẽ hoạt động tốt.

Nó có thể có nghĩa là một tổ chức lại nhỏ của mã grails-appvà một chút khó khăn lúc đầu, nhưng trong một dự án grails lớn, việc tổ chức mọi thứ theo từng gói sẽ rất hợp lý. Chúng tôi sử dụng quy ước đặt tên gói tiêu chuẩn Java com.foo.<app>.<package>.

Có tất cả mọi thứ trong gói mặc định trở thành một trở ngại cho việc tích hợp, như bạn đang thấy.

Bộ điều khiển dường như là một tạo tác Grails (hoặc đồ tạo tác) chống lại việc được đưa vào một gói Java. Có lẽ tôi vẫn chưa tìm ra Conventionđiều đó. ;-)


0

chỉ để hoàn thành ý tưởng:

Từ bên trong gói mặc định, bạn có thể truy cập các đối tượng nằm trong các gói được đặt tên.

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.