2013-03-13 40 views
7

Tôi đã chơi với gói rJava, nhưng vì có vẻ như rJava không nhận thức được các kiểu Java chung, tôi gặp khó khăn trong việc tạo đối tượng java với các tham số kiểu chung chung. Nếu tôi có một lớp java như:rJava generics loại

public class A<T> { 
    private B<T> b; 
    public A(B<T> b) { 
     this.b = b; 
    } 
} 

Tôi muốn tạo ra một Một đối tượng từ phiên R sử dụng .jnew() bằng cách thông qua một đối tượng B đã tạo ra (với tham số kiểu được thuyết minh), nhưng rJava luôn mang đến cho lỗi:

java.lang.NoSuchMethodError: <init> 

Có công việc nào cho việc này không?

+0

Cú pháp chính xác mà bạn đang sử dụng khi bạn gọi '.jnew()' là gì? Bạn đang vượt qua nó đối số?Vui lòng chỉ định chính xác chúng. – Brick

+0

Đây là một ví dụ đã làm việc. Bạn sẽ cần tải xuống bình Tetrad từ [tại đây] (http://www.phil.cmu.edu/projects/tetrad_download/download/tetrad-5.2.1-3.jar) (19mb) và tập dữ liệu mẫu, charity.txt, từ [here] (http://www.phil.cmu.edu/projects/tetrad_download/download/workshop/Data/charity.txt). Thiết lập trong R: 'setwd (" bất cứ nơi nào/bạn/đặt/dữ liệu/")', 'thư viện (rJava)', '.jinit (" đường dẫn/đến/tetrad-5.2.1-3.jar ")'. Tất cả các công việc sau đây: 1. 'filename = .jnew (" java/lang/String "," charity.txt ")', 2. 'datafile = .jnew (" java/io/File ", tên tệp)', 3. 'reader = .jnew (" edu/cmu/tetrad/dữ liệu/DataReader ")', –

+0

4. 'delim = J (" edu/cmu/tetrad/dữ liệu/DelimiterType ")', 5. 'reader $ setDelimiter (delim $ TAB) ', 6.' dataset = reader $ parseTabular (datafile) '. Nhưng sau đây không hoạt động: 7. 'gesinstance = .jnew (" edu/cmu/tetrad/tìm kiếm/Ges ", tập dữ liệu)'. reader $ parseTabular trả về một DataSet, và lớp Ges được cho là được tạo ra với một đối số DataSet. Thật không may điều này không hoạt động. Tôi nghĩ lý do là vì Ges triển khai hai giao diện, GraphSearch và GraphScorer, và GraphScorer chỉ là một đôi. Trong nguồn Java: 'giao diện công khai GraphScorer { double scoreDag (Graph dag); } ' –

Trả lời

1

Có rất nhiều phần chuyển động trong câu hỏi này. Đào thông qua các tài liệu cho các phần khác nhau, tôi nghĩ rằng bạn cần phải làm điều này trên dòng đã phá vỡ:

gesinstance = .jnew("edu/cmu/tetrad/search/Ges", .jcast(dataset, "edu/cmu/tetrad/data/DataSet")) 

Sự khác biệt chính là lời kêu gọi .jcast trên đối số thứ hai. (Tôi không có R cài đặt, vì vậy tôi không thể kiểm tra điều này - Nếu nó không hoạt động, tôi sẽ cập nhật câu trả lời của tôi dựa trên bất kỳ phản hồi nào bạn có thể cung cấp về các thông báo lỗi mới.)

Vì vậy, câu hỏi là "lý do tại sao mà?" Câu trả lời dường như là:

  1. Về phía Java, DataReader.parseTabularData trả về một đối tượng với kiểu DataSet như bạn lưu ý, nhưng DataSet là một giao diện không phải là một lớp. Điều đó nhất thiết có nghĩa là đối tượng thực sự được trả lại là của một số lớp thực hiện giao diện DataSet.
  2. Vì những lý do không rõ ràng với tôi, gói rJava không thực sự xử lý tốt đa hình. Nó đòi hỏi bạn gọi các phương thức với một chữ ký "chính xác" khớp với các đối tượng mà bạn đang truyền đi. Trong trường hợp này, bạn sẽ cần phải "up-cast" từ bất kỳ lớp học cụ thể bạn đã đến giao diện DataSet. Xem tài liệu cho .jnew (https://www.rforge.net/doc/packages/rJava/html/jnew.html), đặc biệt là đối với các đối số mà chúng biểu thị bằng "...". Điều này đề cập đến phần tương ứng của tài liệu cho .jcall (https://www.rforge.net/doc/packages/rJava/html/jcall.html), khi đó giải thích yêu cầu gọi .jcast (https://www.rforge.net/doc/packages/rJava/html/jcast.html) với một số ví dụ.

Lỗi mà bạn nhận được java.lang.NoSuchMethodError: <init> cho bạn biết rằng JVM không thể tìm thấy hàm tạo mà bạn gọi. Đây là điều bí ẩn trong ví dụ mà bạn đã đăng trong phần bình luận. (Nó có thể là tốt để chỉnh sửa câu hỏi của bạn, bằng cách này, và bao gồm thông tin đó lên đó cho hậu thế.) Mã chắc chắn có vẻ đúng, và, biết Java, tôi trực giác dự kiến ​​giao diện để tôn trọng tính đa hình của Java. Do đó (vì bất kỳ lý do gì), giao diện cho R thực hiện kiểu khớp chính xác mà không xem xét thừa kế, rõ ràng là nó sẽ không tìm thấy một hàm tạo vì lý do số 1 ở trên.

Cuối cùng, tôi đã không thực sự gặp phải bất kỳ lớp Java nào sử dụng Generics trong việc khám phá giới hạn Tetrad của tôi. Khi nó quay ra, đó là một cá trích đỏ hoàn toàn mặc dù. Nếu nó là một vấn đề trong tương lai, có thể bạn sẽ muốn kiểm tra "Loại Erasure" (https://docs.oracle.com/javase/tutorial/java/generics/erasure.html). Nếu bạn đang giao tiếp giữa Java và C, C++, Fortran, bất kỳ ngôn ngữ nào mà Java coi là "gốc", thì bạn sẽ xử lý các generics trong mã gốc bằng cách xử lý các biểu mẫu loại bỏ. Tuy nhiên, giao diện rJava có thể khác nhau, vì điều này dường như rơi vào cùng một loại cấu trúc chung mà bạn đã gặp phải trong vấn đề hiện tại của bạn. (Có lẽ xứng đáng với tiền thưởng của chính nó sau này!)

+0

Cảm ơn bạn !! Điều này giải quyết được vấn đề tôi đang gặp phải, và cho tôi hiểu rõ hơn về rJava (và bản thân Java). Tôi không chắc cách chỉnh sửa câu hỏi, bởi vì tôi không hỏi câu hỏi ban đầu, và bạn đã khám phá ra rằng đó là một vấn đề hoàn toàn riêng biệt với những gì tôi đang phải đối mặt. Có lẽ tôi nên làm cho nó một câu hỏi hai phần? –

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