2013-08-08 32 views
6

Tôi đang cố gắng để chơi với sự phản ánh để xem liệu tôi có thể đến một điểm mà tôi có thể gõ vào một tên lớp và ứng dụng của tôi sẽ tải lớp đó và tạo một thể hiện của nó. Sau một vài lần, tôi thấy mình không thể chỉ gắn tên lớp trong Class.forName() mà không có tên gói của nó, vì vậy tôi cố gắng lấy danh sách tất cả các gói sẵn có đã được tải và cố gắng tải lớp tôi nhập vào với mỗi tên gói cho đến khi nó bị trúng.Tại sao sự phản chiếu của tôi tải các lớp kỳ lạ?

Đây là những gì tôi đã có cho đến nay:

BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); 
    String s = ""; 
    do 
    { 
     ClassLoader clsldr = ClassLoader.getSystemClassLoader(); 
     Package[] pkgs = Package.getPackages(); 
     s = console.readLine(); 
     if(s.equals(":exit")) 
     { 
      System.exit(0); 
     } 
     boolean classFound = false; 
     Object loadedClass = null; 
     String classname = ""; 
     for (int i = 0; i < pkgs.length; i++) { 
      Package package1 = pkgs[i]; 
      try 
      { 
       classname = package1.getName().replace('/', '.') + "." + s; 
       clsldr.loadClass(classname); 
       loadedClass = Class.forName(classname); 
       classFound = true; 
      } 
      catch(Exception e) 
      { 

      } 

     } 
     System.out.println("LOADED A CLASS!!!!"); 
     System.out.println(classname); 
     System.out.println(loadedClass); 
    } 
    while(s.length() == 0); 

Nó bán làm việc theo một cách rất lạ. Ví dụ khi tôi gõ vào "Object" tại dấu nhắc nó bằng cách nào đó quản lý để tải sun.net.util.Object, nhưng khi tôi in ra các đối tượng thực tế nó in class java.lang.Object. Tôi nhận được điều tương tự với một số String cũng như một số thứ khác mà tôi đã nhập. Một trong những thú vị tôi đã cố gắng là int - nó nạp sun.net.util.int và khi tôi in đối tượng nó chỉ trả về null. Một điều khác đã xảy ra khi tôi thử Java:

Java 
LOADED A CLASS!!!! 
sun.net.util.Java 
null 

Có ai có bất kỳ đầu mối nào đang xảy ra ở đây không? Có điều gì đặc biệt về gói sun.net.util gây ra điều này không? Tôi không thực sự quan tâm rằng mã của tôi không hoạt động chính xác như tôi muốn, tôi chỉ muốn biết điều gì gây ra hành vi kỳ lạ này.

phiên bản Java:

java version "1.7.0_25"           
Java(TM) SE Runtime Environment (build 1.7.0_25-b17)    
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode) 

Tôi đang trên Windows 8 64 bit nếu mà làm cho bất kỳ sự khác biệt.

Trả lời

0

Tôi chỉ nghĩ về một điều: Tôi không bao giờ thoát khỏi vòng lặp của mình khi tôi học một lớp. Vì vậy, điều này có lẽ thực sự quản lý để có được để java.lang.Object mà bộ lớp nạp đúng, nhưng nó vẫn tiếp tục trong vòng lặp mà ghi đè các lớp thực tế được nạp, và sun.net.util có lẽ là gói cuối cùng được tải trên hệ thống của tôi. Tất cả những gì tôi cần là một tuyên bố phá vỡ và nó sẽ dừng hành vi này.

+0

Ngoại trừ rằng sơ đồ đó sẽ thất bại nếu lớp "lạ" là lớp xuất hiện đầu tiên. Hoặc nếu cả hai lớp là "lạ"; ví dụ. 'java.util.Date' so với' java.sql.Date'. –

0

Các lớp học bắt đầu bằng suncom.sun là các lớp "vệ sinh" nội bộ và hầu như không có giấy tờ được sử dụng bởi nội bộ JVM. Chúng không phải là một phần của API Java và các JVM khác nhau sẽ có các API khác nhau. Thực tế là bạn đang thấy tất cả các nội bộ khác nhau này là lý do tại sao bạn phải chỉ định một tên đủ điều kiện cho API phản chiếu. ;-)

+0

Tôi đã nhận ra rằng ... bạn có nghĩ rằng sẽ an toàn khi bỏ qua 'mặt trời. *' Gói và 'com.sun. *' Để tránh hành vi này? Có cách nào tốt hơn để thực hiện tra cứu lớp/gói không? – Logan

+0

Vì mục đích gì? Chỉ để thử nghiệm? Và bạn không thể bỏ qua hoàn toàn 'com.sun', vì một số lớp này thường xuyên nhìn thấy được trong hoạt động bình thường, thường là sau các giao diện (ví dụ các thuật toán mã hóa được chọn bởi khóa tìm kiếm' String'). Các thư viện SCTP, IIRC, cũng nằm trong 'com.sun' và được sử dụng trực tiếp. – chrylis

+0

Vâng khá nhiều. Tôi muốn có một đâm vào thực hiện một thông dịch viên Java: D – Logan

3

Mã của bạn đang trả về các lớp "lạ" vì những gì nó đang làm là bị hỏng một cách khái niệm. Không có gì trong bất kỳ đặc tả nào cho biết thứ tự vật lý của các mục trong tệp "rt.jar" nên là gì. Chúng chỉ xảy ra trong một trật tự mà kết quả trong việc bạn tìm thấy một "lạ" một trong những cách bạn đang làm lặp đi lặp lại. Trong một bản phát hành Java khác, mã của bạn có thể cung cấp cho bạn lớp "không lạ" Object. Dù bằng cách nào, giả định rằng bạn sẽ có được lớp "đúng" theo cách này là ... thiếu sót.


Bạn nói rằng bạn đang làm điều này vì:

"Tôi muốn lấy một đâm vào làm cho một thông dịch Java"

Vâng, nếu bạn đang đi để thực hiện một thông dịch viên, bạn cần hiểu ngôn ngữ Java. Và một trong những điều bạn cần hiểu là có thể có nhiều lớp học có cùng tên đơn giản trong Java. Điều này có nghĩa rằng ý tưởng quét đường dẫn lớp cho bất kỳ lớp học nào với một tên đơn giản nhất định đơn giản là không thực tế. Bạn sẽ thấy rằng có quá nhiều "va chạm" (tức là các lớp có cùng tên đơn giản) đối với các lớp thường được sử dụng.

Trong Java thông thường, sự cố va chạm này được giải quyết bằng cách tham chiếu đến các lớp theo tên hoàn toàn đủ điều kiện hoặc bằng cách nhập chúng. Để thông dịch viên của bạn có thể sử dụng được, bạn cần triển khai một lược đồ nhập khẩu phản chiếu cơ chế nhập thông thường của Java.

Tóm lại, mương mã ở trên và bắt đầu lại.

+0

Tôi đã chờ câu trả lời này :) như tôi đã nói, đoạn mã này chỉ là để thử nghiệm, tôi có rất ít kinh nghiệm với sự phản chiếu nên tôi chỉ muốn bị ướt chân. Ngoài ra, câu hỏi của tôi là "tại sao mã này tải các lớp kỳ lạ" và không phải "làm thế nào tôi có thể sửa chữa nó". Cảm ơn cho tip mặc dù, tôi có lẽ sẽ đến xung quanh một lần nữa yêu cầu giúp đỡ với các chương trình nhập khẩu :) – Logan

+0

Tôi đã giải quyết phần "tại sao" của câu hỏi của bạn. (Tôi đã không làm như vậy bởi vì tôi nghĩ nó là thừa. Nhưng vì bạn nhấn mạnh ...) –

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