6

I have an Object that sometimes contains a List<Object>. I want to check it with instanceof, and if it is, then add some elements to it.

void add(Object toAdd) {
    Object obj = getValue();
    if (obj instanceof List<?>) {
        List<?> list = obj;
        if (list instanceof List<Object>) {    // Error
            ((List<Object>) list).add(toAdd);
        } else {
            List<Object> newList = new ArrayList<Object>(list);
            newList.add(toAdd);
            setValue(newList);
        }
        return;
    }
    throw new SomeException();
}

And it says I can't check if it is instanceof List<Object> because java doesn't care and erased the type in <>. Does this mean I have to create new ArrayList every time? Or is there a way to check that, eg. with reflection?


C++ why does va_start expect the last non-variadic function argument?

I'm using Visual Studio 2012 to compile this sample code:

#include <stdarg.h>
#include <stdio.h>

const char * __cdecl foo(const char * format, const char * requiredArgument, ...)
{
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    return requiredArgument;
}

int main(int, char **)
{
    foo("The %s is %d pixels wide and %d pixels high.", "box", 300, 200);
    return 0;
}

The debug build of the program terminates normally after printing the message "The box is 300 pixels wide and 200 pixels high.".

The release build crashes with a segmentation fault.

My interpretation for this behavior - but I may be wrong about that, please correct me if so - is that I'm incorrectly specifying a function parameter other than the last non-variadic one in va_start, the only admissible form being here va_start(args, requiredArgument) rather than va_start(args, format) as I would like to have. In other words, I'm misusing va_start in a way that makes the whole program flow unpredictable, and so the segmentation fault is nothing but fine here.

If my assumptions are right, I have two questions now:

  • Why is it even required to specify the last formally declared function parameter in va_start, if choosing anything else is apparently illegal?

  • Why does the picky VC++ compiler not raise a warning for such an easy to detect and potentially critical pitfall?

4

1 に答える 1

5

あなたの要件を完全に理解していなかったため、以前の回答は間違っていました。追加したアイテムがオブジェクトの場合、何かのリストがある限り問題なく追加できます。リストを再作成する必要はありません

void add(Object toAdd) {
    Object obj = getObject();
    if (obj instanceof List<?>) {
        ((List<Object>)obj).add(toAdd);
        return;
    }
    throw new SomeException();
}

アップデート

いくつかのコメントへの回答として、オブジェクトをリストに追加することは問題ありません。また、その後の反復中にそれがどのタイプのオブジェクトであるかを調べることも問題ありません。

List<String> x1 = new ArrayList<String>();
Object c3 = x1;
x1.add("asdsad");
Integer y2 = new Integer(5);
if (c3 instanceof List<?>){
     ((List<Object>)c3).add((Object)y2);
}

for (Object i : (List<Object>)c3){
    if (i instanceof String){
        System.out.println("String: " + (String)i);
    }
    if (i instanceof Integer){
        System.out.println("Integer: "+ (Integer)i);
    }
}
于 2013-02-03T15:51:55.797 に答える