ฉันต้องการสร้างคลาสทั่วไปของแบบฟอร์มนี้:

class MyGenericClass<T extends Number> {}

ปัญหาคือ ฉันต้องการให้ T เป็นจำนวนเต็มหรือยาว แต่ไม่ใช่สองเท่า ดังนั้นการประกาศที่ยอมรับได้เพียงสองประการเท่านั้นคือ:

MyGenericClass<Integer> instance;
MyGenericClass<Long> instance;

มีวิธีใดบ้างที่จะทำเช่นนั้น?

ตอบ

คำตอบคือไม่ อย่างน้อยก็ไม่มีทางทำได้โดยใช้ประเภททั่วไป ฉันอยากจะแนะนำการผสมผสานของยาสามัญและวิธีการจากโรงงานเพื่อทำสิ่งที่คุณต้องการ

class MyGenericClass<T extends Number> {
  public static MyGenericClass<Long> newInstance(Long value) {
    return new MyGenericClass<Long>(value);
  }

  public static MyGenericClass<Integer> newInstance(Integer value) {
    return new MyGenericClass<Integer>(value);
  }

  // hide constructor so you have to use factory methods
  private MyGenericClass(T value) {
    // implement the constructor
  }
  // ... implement the class
  public void frob(T number) {
    // do something with T
  }
}

สิ่งนี้ทำให้มั่นใจได้ว่าสามารถสร้างได้เท่านั้นMyGenericClass<Integer>และMyGenericClass<Long>อินสแตนซ์ แม้ว่าคุณยังสามารถประกาศตัวแปรประเภทMyGenericClass<Double>ได้ แต่จะต้องเป็นค่าว่างเท่านั้น

ไม่ ไม่มีอะไรใน Java generics ที่จะอนุญาตสิ่งนี้ คุณอาจต้องการที่จะต้องพิจารณามีอินเตอร์เฟซที่ไม่ใช่ทั่วไปดำเนินการโดยและFooIntegerImpl FooLongImplเป็นการยากที่จะพูดโดยไม่ทราบเพิ่มเติมเกี่ยวกับสิ่งที่คุณพยายามบรรลุ

คุณขอชั้นเรียนที่ยอมรับทั้งสองประเภท ที่ตอบไปแล้วข้างต้น อย่างไรก็ตาม ฉันจะตอบด้วยว่าคุณจะขยายแนวคิดนั้นไปยังวิธีการภายในคลาสที่คุณใช้โดยไม่จำเป็นต้องสร้างคลาสอื่นสำหรับสิ่งนี้ได้อย่างไร คุณต้องการใช้เพียง : -

  • จำนวนเต็ม
  • ยาว
  • ไม่สองเท่า

    private <T extends Number> T doSomething(T value) throws IllegalArgumentException{
    
           if(value instanceof Integer){
                return (Integer)value;
            }
          else if(value instanceof Long){
                return new value.longValue();
            }
          else
               throw new IllegalArgumentException("I will not handle you lot");
    }