Question

Re-edited...

I'd like to use a superclass constructor which is hidden by the "@hide" Android tag (or whatever it is).

I'm about to extend a class which has been already extended twice (within the Android OS). I'd like to create my own subclass (i.e. outside the Android OS). Example subclass, taken from Android sources:

public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo {
    ...
    private WifiP2pDnsSdServiceInfo(List<String> queryList) {
        super(queryList); // <-- this is what I'm trying to do, too
    }

    public static WifiP2pDnsSdServiceInfo newInstance(String instanceName,
            String serviceType, Map<String, String> txtMap) {
        ...
        ArrayList<String> queries = new ArrayList<String>();
        ...
        return new WifiP2pDnsSdServiceInfo(queries);
    }
}

The superclass looks like this:

public class WifiP2pServiceInfo implements Parcelable {
    ...
    // this is marked as @hidden therefore inaccessible!
    protected WifiP2pServiceInfo(List<String> queryList) {
        if (queryList == null) {
            throw new IllegalArgumentException("query list cannot be null");
        }
        mQueryList = queryList;
    }
}

And all I want to do is to make another kind of WifiP2pServiceInfo, similar to the WifiP2pDnsSdServiceInfo example above. I can't just inherit & call super() because the superclass constructor is tagged by Android's "@hide", therefore unusable without reflection for non-system programmers.

So my question is how to access / call the superclass constructor if I can't do it by a plain super() call? Reflection should come handy here but I'm not very experienced in Java programming.

Was it helpful?

Solution

After some research I'm able to answer the question by myself.

Short answer: I can't do this because if the superclass constructor is protected and hidden, the compiler is going to complain even if I found a way how to call the constructor via reflection.

Long answer: it turns out it's not so complicated to "unhide" this stuff. Following this tutorial I'm able to extend the class to my needs.

See? A lot of noise for nothing, this is the answer I was looking for.

OTHER TIPS

You want to find that constructor and set its availability to true.

But this is a dangerous operation that you should not attempt lightly. It's a dirty secret that private need not mean private, but I would still expect you to honor the wishes of the class designer and not circumvent.

Besides, you don't need to. If I understand your requirement, I've posted an example that will do what you want.

This works, because of this:

The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.

I think you've confused the meaning of the protected modifier.

Parent w/ protected ctor:

package foo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Parent with protected constructor
 * User: MDUFFY
 * Date: 3/27/14
 * Time: 5:18 PM
 * @link http://stackoverflow.com/questions/22698501/reflection-how-to-call-superclass-constructor-which-is-hidden/22698543?noredirect=1#comment34586243_22698543
 */
public class Foo {
    private List<String> x;

    protected Foo(List<String> y) {
        this.x = ((y == null) ? new ArrayList<String>() : new ArrayList<String>(y));
    }

    public List<String> getX() {
        return Collections.unmodifiableList(this.x);
    }

    @Override
    public String toString() {
        return "Foo{" +
                "x=" + x +
                '}';
    }
}

Child extends Parent:

package bar;

import foo.Foo;

import java.util.Arrays;
import java.util.List;

/**
 * Child of parent with protected ctor
 * User: MDUFFY
 * Date: 3/27/14
 * Time: 5:22 PM
 * @link http://stackoverflow.com/questions/22698501/reflection-how-to-call-superclass-constructor-which-is-hidden/22698543?noredirect=1#comment34586243_22698543
 */
public class Bar extends Foo {

    public static void main(String[] args) {
        Bar bar = new Bar(Arrays.asList(args));
        System.out.println(bar);
    }

    public Bar(List<String> y) {
        super(y);
    }


}

This will compile and run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top