ฉันจะส่งคลาสเป็นพารามิเตอร์ใน Java ได้อย่างไร


136

มีวิธีใดบ้างที่จะผ่านคลาสเป็นพารามิเตอร์ใน Java และใช้วิธีการบางอย่างจากคลาสนั้น?

void main()
{
    callClass(that.class)
}

void callClass(???? classObject)
{
    classObject.somefunction
    // or 
    new classObject()
    //something like that ?
}

ฉันใช้ Google Web Toolkit และไม่รองรับการสะท้อนกลับ

คำตอบ:


130
public void foo(Class c){
        try {
            Object ob = c.newInstance();
        } catch (InstantiationException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

วิธีการเรียกใช้วิธีการสะท้อนกลับ

 import java.lang.reflect.*;


   public class method2 {
      public int add(int a, int b)
      {
         return a + b;
      }

      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("method2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Method meth = cls.getMethod(
              "add", partypes);
            method2 methobj = new method2();
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj 
              = meth.invoke(methobj, arglist);
            Integer retval = (Integer)retobj;
            System.out.println(retval.intValue());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }

ยังดู


และฉันจะสร้าง constructor เริ่มต้นหรือวิธีการบางอย่างในชั้นเรียนได้อย่างไร

ขอโทษฉันลืมที่จะเพิ่มเกี่ยวกับชุดเครื่องมือเว็บ Google และสิ่งที่ฉันใช้ชุดเครื่องมือเว็บของ Google และมันไม่สนับสนุนการสะท้อน


ฉันต้องการพูดเกี่ยวกับปรัชญา! Class เป็นชนิดข้อมูลใน Java หรือไม่
Milad Rahimi

40
public void callingMethod(Class neededClass) {
    //Cast the class to the class you need
    //and call your method in the class
    ((ClassBeingCalled)neededClass).methodOfClass();
}

ในการเรียกใช้เมธอดคุณเรียกวิธีนี้:

callingMethod(ClassBeingCalled.class);

ผู้ถามต้องการใช้ตัวสร้างคลาส ' นั่นไม่ใช่เรื่องง่ายและไม่มีใครพูดถึงที่นี่ โพสต์นี้ยังมีตัวเลือก (อ่านความคิดเห็นทั้งหมดเพราะคำตอบที่ได้รับการยอมรับไม่ทำงาน): stackoverflow.com/questions/234600/... มันค่อนข้างยุ่งเหยิงและคอมไพเลอร์คำเตือนที่คุณได้รับแนะนำว่าพวกเขาไม่ต้องการให้คนทำกับ Java ง่ายยิ่งขึ้นใน Python
:)

9

สร้างวิธีการของคุณเพื่อยอมรับมัน -

public <T> void printClassNameAndCreateList(Class<T> className){
    //example access 1
    System.out.print(className.getName());

    //example access 2
    ArrayList<T> list = new ArrayList<T>();
    //note that if you create a list this way, you will have to cast input
    list.add((T)nameOfObject);
}

โทรวิธี -

printClassNameAndCreateList(SomeClass.class);

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

protected Class postExceptionActivityIn;

protected <T extends PostExceptionActivity>  void  setPostExceptionActivityIn(Class <T> postExceptionActivityIn) {
    this.postExceptionActivityIn = postExceptionActivityIn;
}

สำหรับข้อมูลเพิ่มเติมค้นหา Reflection and Generics


4

ใช้

void callClass(Class classObject)
{
   //do something with class
}

A Classยังเป็นวัตถุ Java ดังนั้นคุณสามารถอ้างอิงได้โดยใช้ชนิดของวัตถุ

อ่านข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้จากเอกสารที่เป็นทางการ


2

สิ่งนี้ไม่ใช่เรื่องง่าย นี่คือวิธีการที่เรียกใช้วิธีการคงที่:

public static Object callStaticMethod(
    // class that contains the static method
    final Class<?> clazz,
    // method name
    final String methodName,
    // optional method parameters
    final Object... parameters) throws Exception{
    for(final Method method : clazz.getMethods()){
        if(method.getName().equals(methodName)){
            final Class<?>[] paramTypes = method.getParameterTypes();
            if(parameters.length != paramTypes.length){
                continue;
            }
            boolean compatible = true;
            for(int i = 0; i < paramTypes.length; i++){
                final Class<?> paramType = paramTypes[i];
                final Object param = parameters[i];
                if(param != null && !paramType.isInstance(param)){
                    compatible = false;
                    break;
                }

            }
            if(compatible){
                return method.invoke(/* static invocation */null,
                    parameters);
            }
        }
    }
    throw new NoSuchMethodException(methodName);
}

อัปเดต: เดี๋ยวก่อนฉันเพิ่งเห็นแท็ก gwt ในคำถาม คุณไม่สามารถใช้การสะท้อนใน GWT


1

ฉันไม่แน่ใจว่าคุณกำลังพยายามทำให้สำเร็จ แต่คุณอาจต้องการพิจารณาว่าการผ่านชั้นเรียนอาจไม่เป็นสิ่งที่คุณต้องทำจริง ๆ ในหลายกรณีการจัดการกับ Class เช่นนี้จะถูกห่อหุ้มอย่างง่ายดายภายในรูปแบบของโรงงานบางประเภทและการใช้งานนั้นทำผ่านอินเตอร์เฟส นี่เป็นหนึ่งในหลายสิบบทความในรูปแบบนั้น: http://today.java.net/pub/a/today/2005/03/09/factory.html

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


0

อย่างที่คุณบอกว่า GWT ไม่สนับสนุนการสะท้อนกลับ คุณควรใช้การรวมที่รอการตัดบัญชีแทนการสะท้อนหรือห้องสมุดบุคคลที่สามเช่นgwt-entสำหรับการสะท้อนการสนับสนุนที่ชั้น gwt



-1

ดูการสอนการไตร่ตรองและการสะท้อนกลับ API ของ Java:

https://community.oracle.com/docs/DOC-983192 ป้อนคำอธิบายลิงก์ที่นี่

และ

http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html


OP ระบุไว้อย่างชัดเจนว่าเขาใช้ GWT ซึ่งไม่สนับสนุนการสะท้อน
Knarf

2
คำถามนี้ได้รับการแก้ไขนานหลังจากคำตอบของฉัน คำถามเดิมไม่มีคำใบ้นั้น คำตอบที่ได้รับการยอมรับหมายถึงการสะท้อนกลับ
Marcus Gründler

-1

ชั้นเป็นพารามิเตอร์ ตัวอย่าง.

สามชั้น:

class TestCar {

    private int UnlockCode = 111;
    protected boolean hasAirCondition = true;
    String brand = "Ford";
    public String licensePlate = "Arizona 111";
}

-

class Terminal {

public void hackCar(TestCar car) {
     System.out.println(car.hasAirCondition);
     System.out.println(car.licensePlate);
     System.out.println(car.brand);
     }
}

-

class Story {

    public static void main(String args[]) {
        TestCar testCar = new TestCar();
        Terminal terminal = new Terminal();
        terminal.hackCar(testCar);
    }

}

ในวิธีการเรียนชั้นขั้ว hackCar () ใช้คลาส TestCar เป็นพารามิเตอร์


1
อืมม์ไม่มันก็นำตัวอย่างของเทสคาร์
towc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.