You could always write a generic method to do it for you:
static <T> void testFoo(Foo<T> f) {
f.test(f);
}
static void boom() {
Foo<?> f = new Foo<String>();
testFoo(f); // works just fine
}
So the problem isn't that what you're doing is fundamentally unsafe, it's just that Java has no syntax to capture `?` except through a generic type parameter on a method or class.