2014-05-23 17 views
7

Vui lòng xem toàn bộ câu hỏi để có ý tưởng hoàn chỉnh.Tại sao tôi không thể tham chiếu tĩnh phương thức tĩnh của lớp bên trong trên một lớp chung?

Trước tiên cho lớp Box được đưa ra như sau: -

public class Box <T>{ 
    private T t; 

    public void set(T t){ 
     this.t = t; 
     System.out.println("value:\n"); 
     System.out.printf("%s", t.toString()); 
    } 
    public T get() { 
     return t; 
    } 
    static int retInt(){ 
     return 5; 

    } 
    public <U extends Number> void inspect(U u){ 
      System.out.println("T: " + t.getClass().getName()); 
      System.out.println("U: " + u.getClass().getName()); 
     } 

} 

Generic lớp Util như đưa ra dưới đây: -

public class Util<T>{ 
    private T t; 

    //Generic method 
    public <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) { 
     return p1.getKey().equals(p2.getKey()) && 
       p1.getValue().equals(p2.getValue()); 
    } 

    /* Static generic or non-generic methods can be declared in generic class 
     but they can not make use of generic parameter type(as generics static  
     methods using class type variable must know the type argument 
     (i.e value of type parameter); and knowledge of type argument is 
     possible only when object of same generic class are instantiated 
     (meaning assigning value of generic type parameter <T> or better to 
     say declared object have it's type argument; for example 
     as in List<T> replace T with Integer,String, Float etc); 
     but static method may be called without having 
     instance of class; so such declaration for static generic method are 
     not allowed) here it is <T>; like for example as shown below 

     public static int checkFun(T t){ 
      return 5; 
     } // this generate compiler error complaining "can not make static 
     // reference to non-static type T".   
    */ 


    public static <K> boolean cmp(Box<K> b1, Box<K> b2){ 
     // implement comparator to compare but here 
     return true; 
    } 

    // Inner class Pair 
    public class Pair <K, V> { 
     private K key; 
     private V value; 

     // Generic constructor 
     public Pair(K key, V value) { 
      this.key = key; 
      this.value = value; 
     } 

     public void setKey(K key) { 
      int i = 6; 
      if(i >4 || i<9); 
      this.key = key; 
     } 

     public void setValue(V value) { 
      this.value = value; 
     } 

     public K getKey(){ 
      return key; 
     } 

     public V getValue(){ 
      return value; 
     } 

    } 

    public void main1() {   
     //The complete syntax for invoking this method would be: 
     // <Integer, String> new Util<T>(). 
     Pair<Integer, String> p1 = new Pair<Integer,String>(1, "apple"); 
     Pair<Integer, String> p2 = new Pair<Integer, String>(2, "pear"); 
     boolean same = compare(p1, p2); 
     //boolean same = true; 
     if(same)System.out.println("it is true: they are the same"); 
     else System.out.println("nah! they are not the same..."); 

     //boolean sm = compare(); 
    } 

    public static void main (String[] args) /*throws FileNotFoundException */{ 
     //new Util<Integer>(). main1(); 

     Util<Integer> util = new Util<>(); 
     util.main1(); 
    } 
} 

Trên mã biên dịch và thực thi tốt, cảm giác khó chịu của tôi nằm ở đây:

Nếu chúng tôi thêm static công cụ sửa đổi vào phương pháp

public <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) -------(1) 
// called in method main1() 

và làm cho nó

public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2)  -------(2) 

sau đó trình biên dịch sẽ phàn nàn rằng Không thể làm cho một tham chiếu tĩnh để loại không tĩnh Pair trong khi phương pháp tương tự

public static <K> boolean cmp(Box<K> b1, Box<K> b2) -------(3) 

cũng là tĩnh nhưng doesn không phàn nàn. Mặc dù chúng tôi không sử dụng tham số kiểu <T> trong cả hai phương pháp but một phương thức big but trong phương thức chúng tôi đang nói từ eq-1 đối số mà nó sử dụng là từ lớp bên trong Pair (vì vậy lý do của sự mơ hồ của tôi có thể được giải thích với tham chiếu đến tính năng này).

Nhưng vẫn còn; về mặt logic, tôi cảm thấy rằng việc thêm sửa đổi static thành phương thức trong eq-1 không được tạo ra lỗi thời gian biên dịch bởi vì bất cứ khi nào phương thức trong eq-2 được gọi là phương thức đó để gọi với đối số chính xác cho phương thức trong eq-2 và nó phải được phép gọi như một phương pháp tĩnh.

Câu hỏi: - lời giải thích cho không sử dụng modifier tĩnh cho phương pháp này là gì:

public <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) 

Thanks for the help.

Trả lời

9

Lý do cho việc này là tham số kiểu trên lớp Util và lớp bên trong Cặp là không tĩnh. Bởi vì Pair là một lớp bên trong không tĩnh, nó có thể sử dụng tham số kiểu T của Util (mặc dù trong trường hợp này nó không). Do đó khi sử dụng Pair, cần phải chỉ định T, hoặc bằng cách truy cập nó trong ngữ cảnh của một Util instance (trong đó T có sẵn) hoặc bằng cách truy cập nó thông qua một Util<T> cụ thể, ví dụ: Util<Integer>.Pair<String,Object>. Một cách khác để nghĩ về nó là loại Cặp phụ thuộc vào tham số kiểu của Util và Util<String>.Pair<K,V> không tương thích với Util<Object>.Pair<K,V>.

Để giữ cho kiểu tham số T trên util và giữ Pair như một lớp bên trong không tĩnh, bạn có thể thay đổi chữ ký của so sánh với

public static <T, K, V> boolean compare(Util<T>.Pair<K, V> p1, Util<T>.Pair<K, V> p2) 

hoặc

public static <K,V> boolean compare(Util<?>.Pair<K,V> p1, Util<?>.Pair<K,V> p2) 

mà có thể vì sự khởi tạo của T không liên quan đến phần thân của phương thức.

Là một thay thế, kể từ khi Pair không đề cập đến bất cứ điều gì (không tĩnh) bên trong util bạn có thể thay đổi định nghĩa của Pair là

public static class Pair <K, V> { /* ... */ } 

Cuối cùng cho đầy đủ, nếu util không có một loại tham số sau đó

public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) 

public class Pair<K, V> { /* ... */ } 

sẽ là tốt.

+0

, Cảm ơn người đàn ông. Tôi tin rằng bạn đã bao gồm hầu như tất cả các phần. Tôi đã có một giải pháp cho vấn đề nhưng lời giải thích đầu tiên bạn đưa ra để giữ tham số kiểu T đã loại bỏ một phần nghi ngờ của tôi. Nhưng tôi vẫn không thể có được đầu của tôi xung quanh trình biên dịch phàn nàn vì không sử dụng sửa đổi tĩnh. Bạn đã báo giá ** Vì vậy, Pair phải được sử dụng trong một ngữ cảnh có T đặc biệt có sẵn ** unquote. Như tôi đã nói trong câu hỏi của mình (Và tôi tin rằng, tôi có thể sai) rằng thông tin ** T ** sẽ có sẵn trong khi tạo đối tượng của ** Pair ** class (ở đây trong phương thức ** main1() ** không tĩnh). – zeal

+0

như tôi đã nói ở trên phương thức gọi ** main1() ** yêu cầu đối số (giá trị) để nhập tham số để Object của lớp ** Pair ** sẽ tự động có giá trị ** T **, đối tượng của lớp Pair có thể sử dụng (mặc dù ở đây họ không sử dụng). Vì vậy, hãy ném một số ánh sáng về vấn đề ở đây để sự nhầm lẫn của tôi bị xóa. – zeal

+0

@ bạn nói đúng là một chút không rõ ràng, tôi đã thay đổi câu trả lời đó. Hy vọng rằng nó có ý nghĩa hơn bây giờ. Tôi cũng đã thêm một số lưu ý về các ký tự đại diện chung bị thiếu trước đây. –

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