7

I have two classes and an interface (for example DatabaseModel, LocalStore, and InternalModelInterface). They're defined as follows;

public class DatabaseModel {
  // ...
  public static final String KEY_PARAM1 = "param1";
}

public class LocalStore implements InternalModelInterface {
  // ...
  public void function () {
    String temp = InternalModelInterface.COLUMN_PARAM1;
  }
}

public interface InternalModelInterface {
  public static final String COLUMN_PARAM1 = DatabaseModel.KEY_PARAM1;
  // ...
}

The issue I'm experiencing is that at runtime, when I call localStore.function(), temp is being assigned null, as InternalModelInterface.COLUMN_PARAM1 is null. Does this make sense? Shouldn't InternalModelInterface.COLUMN_PARAM1 be evaluated at compile time and inlined?

This is for an Android application. Thanks in advance.

I'll further explain to clarify any confusion.

Objects of the DatabaseModel class are instantiated as a JSON response is parsed. The constants defined in the DatabaseModel class represent the keys to look for in the JSON response.

The InternalModelInterface defines the column names used in the local (cache) database on the device. For several reasons (including they keys being illegal column names in SQLite), I'm not reusing the keys as column names.

The reason I'm using an interface and not just a plain class is that the interface also specifies required methods that need to be implemented by the third class, LocalStore.

Amit Vaghela
  • 22,772
  • 22
  • 86
  • 142
1in9ui5t
  • 126
  • 1
  • 7
  • 3
    shouldn't it be `DatabaseModel.KEY_PARAM1`? – mre May 19 '11 at 16:44
  • No, the DataModel.KEY_PARAM1 mimicks the remote representation of the parameter (in my case, the JSON response key), whereas the InternalModelInterface.COLUMN_PARAM1 is the local representation of the (cache) database table column name. – 1in9ui5t May 19 '11 at 16:50
  • 1
    Where's the `DataModel` class? – Mike Baranczak May 19 '11 at 16:51
  • The two classes and the interface reside on the Android device. None of this is server code. – 1in9ui5t May 19 '11 at 16:52
  • 2
    @1in9ui5t, then why are you including a code snippet of the `DatabaseModel` when it's not even used? I thought perhaps your problem was a simple typo (i.e. `DataModel` != `DatabaseModel`). if this is not the case, then you need to provide use with more relevant code, let's say, the `DataModel` class? – mre May 19 '11 at 16:53
  • Well the DataModel is used, I have just left out the rest of my code. – 1in9ui5t May 19 '11 at 16:55
  • @sthupahsmaht you're right that's a typo. I'll fix it. Thanks. – 1in9ui5t May 19 '11 at 17:01
  • @1in9ui5t, no problem. is the problem resolved now? if so, want me to make my comment an answer so you can accept it? – mre May 19 '11 at 17:02
  • @sthupahsmaht No, the problem remains. This is sample code. – 1in9ui5t May 19 '11 at 17:07
  • Do you get different results if you change it to `String temp = COLUMN_PARAM1;` ? You shouldn't need to specify the `InternalModelInterface` if the class itself extends that interface – matt b May 19 '11 at 17:17
  • @matt b I did try that to no avail. – 1in9ui5t May 19 '11 at 17:19
  • I couldn't reproduce your error with 1.4, 1.5 or 1.6 compiler level. Where are you instantiating your `LocalStore` instance? – rekaszeru May 19 '11 at 17:22
  • Are you sure, that `DatabaseModel.KEY_PARAM1` is not null? If you assign `temp = DatabaseModel.KEY_PARAM1` will it work? – Mikita Belahlazau May 19 '11 at 17:25
  • Did you try doing a clean build? Constants may be inlined by the compiler, so if you modify DatabaseModel but not InternalModelInterface, you might wind up with an out-of-date value. – Mike Baranczak May 19 '11 at 17:37
  • @Nikita Beloglazov Yes, that assignment works correctly. – 1in9ui5t May 19 '11 at 17:37
  • @rekaszeru I was hesitant in posting this question in the first place. It seems improbable on all counts, it is challenging how Dalvik deals with bytecode or worse, javac. LocalStore if you're familiar with Android is actually a SQLiteOpenHelper, and I'm instantiating it within the constructor for a CustomModelItemizedOverlay. – 1in9ui5t May 19 '11 at 17:42
  • Eclipse complains about my declaration of CustomModelItemizedOverlay (which extends ItemizedOverlay). The error message reads "ItemizedOverlay is a raw type. References to generic type ItemizedOverlay should be parametrized. My class declaration reads: public class CustomModelItemizedOverlay extends ItemizedOverlay { //... } – 1in9ui5t May 19 '11 at 17:46
  • @1in9ui5t that's just a warning, that you can bypass either modifying your class declaration to `public class CustomModelItemizedOverlay extends ItemizedOverlay` or by ignoring it in the workspace settings. – rekaszeru May 19 '11 at 18:09

2 Answers2

3

JLS3 §8.3.2.1, §9.3.1 http://java.sun.com/docs/books/jls/third_edition/html/classes.html#38010

at run time, static variables that are final and that are initialized with compile-time constant values are initialized first. This also applies to such fields in interfaces (§9.3.1). These variables are "constants" that will never be observed to have their default initial values (§4.12.5), even by devious programs.

So null should never be observed in your example. It's an Android bug then.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • thanks for your response. I'm on the same page with the JLS. After some debugging, it seems to be an Eclipse issue and not an Android one. – 1in9ui5t May 19 '11 at 19:42
  • 1
    @1in9ui5t Hi, did you find a fix for this bug? – sidon Jan 09 '13 at 11:55
  • I am facing the same issue. Wouldn't be surprised if this was an Android bug. – W.K.S Dec 01 '14 at 05:13
  • Late to the party... I am experiencing a similar issue in Android studio, so while it may be an Eclipse bug as well, I have a hard time seeing the bug being duplicated across both IDE's. – akousmata May 01 '15 at 18:02
0

I'm not and android expert but I think that if you don't create an instance of the class, it's optimised out at compile time. If you create a constructor for DatabaseModel and instantiate it somewhere it seems to solve this for me.

Dan
  • 1