1

I've a two classes in different packages like this. Base class:

package com.example.artpackageprivate.base;

public class Base {

    protected final Context mContext;

    public Base(final Context context) {
        mContext = context;
    }

    public void foo() {
        boo();
    }

    /*package*/ void boo()
    {
        Toast.makeText(mContext, "Base", Toast.LENGTH_LONG).show();
    }

    public static void redirect(Base object) {
        object.boo();
    }

and child class:

com.example.artpackageprivate.child;

public class Child extends Base {

    public Child(Context context) {
        super(context);
    }

    @Override
    public void foo() {
        boo();
    }

    public /*or whatever*/ void boo()
    {
        Toast.makeText(mContext, "Child", Toast.LENGTH_LONG).show();
    }

I have an object of class Child and I call child.boo() I expect to get "Child" printed. This is really what I usually get. With Dalvik it actually works always. But when I switch to ART I'm getting 2 different outputs.

When the child.boo() is called from "package tree" of Child class I get "Child". The problem is when I call it from a class in package com.example.artpackageprivate.base. The result is "Base" although the object is an instance of class Child.

Here is the Activity class code which is making the calls (Activity contains only 2 buttons):

package com.example.artpackageprivate;

public class MainActivity extends Activity {

    private Base mBase;
    private Child mChild;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mBase = new Base(this);
        mChild = new Child(this);
    }

    public void onChildButtonClick(View view) {
        Base.redirect(mChild);
    }

    public void onBaseButtonClick(View view) {
        mBase.foo();
    }
}

Running this code on Dalvik and on ART (both android Kitkat) I'm getting 2 different results. Pressing BaseButton the result is always "Base". Result of ChildButton is "Child" on Dalvik and "Base" on ART. How is this possible? Is it some kind of bug in ART?

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
bio007
  • 893
  • 11
  • 20

1 Answers1

0

It was a known bug in Dalvik (and it won't be fixed in Dalvik):

https://code.google.com/p/android/issues/detail?id=60406

Since Base.boo() is package private : it cannot be overridden in another package. So result with ART is correct ; result with Dalvik is wrong.

The concept of "package tree" don't exists in java :

com.company.a
com.company.a.b
com.company.b

are just 3 different packages : there is no special relation between com.company.a and com.company.a.b

ben75
  • 29,217
  • 10
  • 88
  • 134
  • OK, but Java is OK with the same signature private methods in parent and child. (not overriding) Then when you call this method on instance of parent the parent's method get called and on child's instance the child's method get called. Here on child's instance object is parent's method called. That is weird. Above all when you call `mChild.boo()` instead of `Base.redirect(mChild)` you will get correct result. – bio007 Oct 29 '14 at 10:55