Nhận loại lớp từ chuỗi


83

Tôi có một Stringcái tên của một lớp nói "Ex"(không có .classphần mở rộng). Tôi muốn gán nó cho một Classbiến, như sau:

Class cls = (string).class

Làm thế nào tôi có thể làm điều đó?


điều gì sẽ xảy ra nếu lớp nằm trong dự án khác nhau?
Steven

Nhận xét của bạn: Cái gì! ??? Nếu lớp của bạn nằm trong một dự án khác, thì nó có phụ thuộc vào IDE của bạn không? Theo như ứng dụng của bạn có liên quan, dù sao thì nó cũng giống như trong cùng một dự án vì các thư viện của nó được tham chiếu bên ngoài. Giống như, bạn biết rằng các lớp API Java không có trong dự án của bạn, phải không? Tuy nhiên, trình biên dịch cho IDE của bạn biết tìm chúng ở đâu, nếu IDE của bạn được thiết lập chính xác. Điều tương tự cũng áp dụng cho các lớp của bạn từ một dự án khác.
user919860

Câu trả lời:


165
Class<?> cls = Class.forName(className);

Nhưng bạn classNamephải hoàn toàn đủ điều kiện - tức làcom.mycompany.MyClass


2
nó ném ClassNotFound Exception
Steven

1
sau đó một trong hai lớp không phải là trên classpath hoặc bạn không đi qua các tên lớp đầy đủ ví dụ com.mycompany.project.ClassName
Hans Westerbeek

classNamebạn đang vượt qua giá trị nào? Có một lớp như vậy trên classpath của bạn không?
Bozho

vâng Class là trong cùng một gói
Steven

1
Tôi có cùng một vấn đề với ClassNotFoundException. Bí quyết là xử lý ngoại lệ trong một lần thử bắt. Một cái gì đó như thế này:try { Class<?> cls = Class.forName("com.company.MyClass"); } catch (ClassNotFoundException ex) { /* do something to handle the case when the string isn't valid and therefor the class can't be found */ }
kumaheiyama

43
String clsName = "Ex";  // use fully qualified name
Class cls = Class.forName(clsName);
Object clsInstance = (Object) cls.newInstance();

Kiểm tra đường dẫn Hướng dẫn Java về Phản chiếu tại http://java.sun.com/docs/books/tutorial/reflect/TOC.html để biết thêm chi tiết.


3
Câu trả lời của Bozho có thể có nhiều điểm hơn, nhưng tôi nghĩ rằng câu trả lời của bạn mang tính mô tả nhiều hơn. Tái bút. Tại sao tên bạn là JuanZe ??? Gần giống như âm thanh pha trộn giữa tiếng Tây Ban Nha và tiếng Trung Quốc. : D. Có một số loại ý nghĩa thông minh đằng sau nó?
user919860

Tôi đang làm việc với một dự án web Động trong nhật thực. Tôi đang sử dụng mã trên để tìm nạp một Lớp. nhưng nó trả về ClassNotFoundException, khi tôi sử dụng một biến chuỗi như thế này: String clsName = "com.mydoamin.className"; Class cls = Class.forName(clsName); Nếu mã cứng là tên lớp đủ điều kiện làm tham số thì mọi thứ hoạt động tốt. Bất kì lời đề nghị nào?
Dibyanshu Jaiswal

8

Bạn có thể sử dụng forNamephương pháp Class:

Class cls = Class.forName(clsName);
Object obj = cls.newInstance();

Tôi đang làm việc với một dự án web Động trong nhật thực. Tôi đang sử dụng mã trên để tìm nạp một Lớp. nhưng nó trả về ClassNotFoundException, khi tôi sử dụng một biến chuỗi như thế này: String clsName = "com.mydoamin.className"; Class cls = Class.forName(clsName); Nếu mã cứng là tên lớp đủ điều kiện làm tham số thì mọi thứ hoạt động tốt. Bất kì lời đề nghị nào?
Dibyanshu Jaiswal

@djthequest Nếu clsNamebiến của chúng ta chứa tên lớp đủ điều kiện thì không có sự khác biệt giữa việc sử dụng nó và chuỗi mã cứng. Bạn có thể không có lớp bạn cần trong classpath. Nó có thể hữu ích để khởi tạo một lớp chung từ cùng một jar trong mã khởi động của bạn để đảm bảo rằng thư viện có trong trình nạp lớp.
rsp

cảm ơn vì phản hồi của bạn, nhưng thay vì biến nếu tôi hardcode chuỗi, hoạt động vây, nó có nghĩa là các lớp nằm trong đường dẫn lớp, phải không? Sau đó tôi đã tìm ra, Class.forName()phương thức mong đợi một finalbiến. Một biến đơn giản sẽ không hoạt động.
Dibyanshu Jaiswal

4

Bạn có thể lấy tham chiếu Lớp của bất kỳ lớp nào trong thời gian chạy thông qua Khái niệm phản chiếu Java.

Kiểm tra mã bên dưới. Giải thích được đưa ra dưới đây

Đây là một ví dụ sử dụng Lớp được trả về để tạo một phiên bản của AClass:

package com.xyzws;
class AClass {
    public AClass() {
        System.out.println("AClass's Constructor"); 
    }  
    static {   
        System.out.println("static block in AClass");  
    }
}
public class Program {   
    public static void main(String[] args) {
        try {       
            System.out.println("The first time calls forName:");   
            Class c = Class.forName("com.xyzws.AClass");      
            AClass a = (AClass)c.newInstance();    
            System.out.println("The second time calls forName:");  
            Class c1 = Class.forName("com.xyzws.AClass"); 
        } catch (ClassNotFoundException e) { 
            // ...
        } catch (InstantiationException e) {  
            // ...
        } catch (IllegalAccessException e) { 
            // ...
        }     
    }
}

Đầu ra được in là

    The first time calls forName:
    static block in AClass
    AClass's Constructor
    The second time calls forName:

Lớp đã được tải nên không có "khối tĩnh trong AClass" thứ hai

Giải thích bên dưới

Class.ForName được gọi để lấy một Đối tượng Lớp

Bằng cách sử dụng Đối tượng Lớp, chúng tôi đang tạo một phiên bản mới của Lớp.

Bất kỳ nghi ngờ về điều này cho tôi biết


điều gì sẽ xảy ra nếu lớp nằm trong dự án khác nhau?
Steven

1
Bạn có thể lấy tệp jar của proect đó và chỉ định tên lớp một số thứ như Class.forName ("oracle.jdbc.driver.OracleDriver")
gmhk Ngày


2

Không chắc bạn đang hỏi gì, nhưng ... Class.forname , có thể không?


nó ném ClassNotFound Exception
Steven

điều gì sẽ xảy ra nếu lớp nằm trong dự án khác nhau?
Steven

1
Tôi thấy rằng không ai trả lời câu hỏi của bạn. Sẽ không thành vấn đề nếu nó nằm trong một dự án khác miễn là trình biên dịch biết nơi để tìm. Vì có thể bạn đang sử dụng IDE, nó có thể chỉ phụ thuộc vào IDE. Về tài liệu tham khảo, bạn biết rằng tất cả các lớp mà bạn tham chiếu từ các thư viện Java không có trong dự án của bạn, phải không? Tuy nhiên, trình biên dịch biết phải tìm chúng ở đâu vì nó biết rằng chúng được tham chiếu từ bên ngoài. Có vẻ như bạn cần học lập trình Java cơ bản khi định học lập trình Java nâng cao. : |
user919860
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.