Using Reflection to call a method on a field

2019-07-15 03:41发布

Okay been working on this too long and can't get it to work. I have a list of Thread types that can be different classes i.e. WriteFileData(extends Thread). I want to for loop through that list and do a call to add to queue a byte array. I currently have this in a Broker class

// consumers is filled with different Thread types all having a queue
// variable of type LinkedBlockingQueue
ArrayList<Thread> consumers = new ArrayList<Thread>();

synchronized void insert(final byte[] send) throws InterruptedException {
    for (final Thread c : consumers) {
        if (c instanceof WriteFileData) {
            ((WriteFileData)c).queue.add(send);
        } 
        ...other class threads...
}

but what I want to do is something more along the lines of

synchronized void insert(final byte[] send) throws InterruptedException {
    for (final Thread c : consumers) {
       Class<?> cls = Class.forName(c.getClass().getName());
       Field field = cls.getDeclaredField("queue");
       Class<?> cf = Class.forName(field.getType().getName());
       Class[] params = new Class[]{Object.class};

       Method meth = cf.getMethod("offer", params);

       meth.invoke(cf, send);  // errors at this line....

EDIT: Fixed "method not found error" but now can't seem to invoke method due to I'm sending it an Array and its method wants just an Object.

.... alas it errors out at meth.invoke. Not sure how to do this as this is many levels deep, I wanted to use the add method on queue but that is one more layer of class abstraction.

Here is what WriteFileData has...

public class WriteFileData extends Thread {
    LinkedBlockingQueue<byte[]> queue = new LinkedBlockingQueue<byte[]>();

...
}

1条回答
不美不萌又怎样
2楼-- · 2019-07-15 04:24

Here is what I did with some advice from @Erik.

Here is WriteFileData with added method add(byte[] send) ...

public class WriteFileData extends Thread {
    private LinkedBlockingQueue<byte[]> queue = new LinkedBlockingQueue<byte[]>();

    public void add(byte[] send) {
        queue.add(send);
    }

...
}

And now my Broker class method looks like this:

public synchronized void insert(final byte[] send) {
    for (final Thread c : consumers) {
    try {
        Class<?> cls = Class.forName(c.getClass().getName());
        Method meth = cls.getMethod("add", new Class[]{byte[].class});
        meth.invoke(c, send);
查看更多
登录 后发表回答