Scusate in anticipo per la lunga domanda ma tutto dovrebbe essere semplice e chiaro cosa sta succedendo, grazie per dare un'occhiata. Si noti che questo non è in realtà codice, solo pseudo codice per comprendere l'implementazione dell'applicazione.Ampliamento da byte a Int (bug Marshmallow)
Problema
Byte di non stanno ampliando al vero valore numerico. Nota: level = -1
rappresenta un gioco che non è stato avviato. level == 24
rappresenta la fine del gioco.
Classe 1
private byte level = -1;
private byte stage = 0;
@NonNull private final Stages[][] stages = new Stages[25][13];
public byte getLevel() {
return level;
}
public void nextLevel() {
// expect: 0
level++;
// stages[ 128][ 0] (ArrayIndexOutOfBounds)
stages[level][stage] = new Stage();
}
Classe 2 estende Classe 1
@NonNull private final byte[][] values = new byte[25][4];
public byte getScore (final byte level, final byte player) {
// values[ 255][ 2] (ArrayIndexOutOfBounds)
return values[level][player];
}
// expecting: -1 >= 0 (false)
// runtime: 255 >= 0 (true)
if (Class1.getLevel() >= 0)
getScore(Class1.getLevel(), 2);
binario
8 bit (byte)
-1 == 1111 1111
-128 == 1000 0000
127 == 0111 1111
32 bit (intero)
-1 == 1111 1111 1111 1111 1111 1111 1111 1111
127 == 0000 0000 0000 0000 0000 0000 0111 1111
128 == 0000 0000 0000 0000 0000 0000 1000 0000
255 == 0000 0000 0000 0000 0000 0000 1111 1111
cosa ha funzionato
Utilizzando la classe wrapper
public Byte level = -1;
domanda
Capisco il problema è la rappresentazione binaria del numero viene utilizzata direttamente quando si allarga da byte a int. Il mio numero va letteralmente da 8 bit 1111 1111
a 32 bit 0000 0000 0000 0000 0000 0000 1111 1111
. La mia domanda è: perché Java (o perché non è in questa situazione/ambiente) converte il numero nel vero valore numerico quando si allarga invece di riempire gli zeri con la rappresentazione binaria grezza.
Questo sembra accadere solo a numeri negativi, presumo perché i numeri positivi hanno la stessa rappresentazione bit prima e dopo l'allargamento.
Perché il mio numero non passa da 8 bit 1111 1111
a 32 bit 1111 1111 1111 1111 1111 1111 1111 1111
? Perché l'incremento postfisso crea un valore di 128 ..? C'è una soluzione migliore a questo problema oltre a quella con cui sono attualmente bloccato?
Preferisco non utilizzare questa soluzione senza conoscere il problema di sottolineatura perché il problema può tranquillamente (eseguire senza errori) interrompere l'algoritmo delle applicazioni; Quindi è con molto apprezzamento se qualcuno può spiegarmi questo problema per favore.
Grazie, Jay
Corrente di funzionamento Ambiente
JDK 1.8.076
OS X El Capitan
Android Studio 2.2 Preview 2
buildToolsVersion '23 .0.3'
classpath 'com.android.tools.build:gradle:2.2.0-alpha2'
Emulator Nexus 6P API 23 x86
Conclusione
Sono stato in grado di limitare il problema a dispositivi esclusivamente Android 23 (Marshmallow). Ho segnalato il bug a Google Inc. Grazie per l'aiuto di tutti, darò un avvertimento agli utenti di Android 23 (Marshmallow) poiché il bug non compare in Android N, Android 22 e versioni precedenti.
Penso che la ragione forse non sia la rappresentazione di bit, ma il fatto che si usi il byte in un indice di array. Questo potrebbe cambiare le regole di conversione. Ho provato a trovare fatti nelle specifiche del linguaggio java ma non ho ancora trovato un suggerimento. Puoi provare ad assegnare i valori dell'indice a int locali prima di utilizzarli nell'indice dell'array? Cambia sth? – thst
Ho trovato un suggerimento. Ancora bisogno di capire chiaramente: nel contesto dell'indice dell'array, viene applicata la conversione unaria. L'esempio mostra che 'byte b = -1; int i = -b; -> i = 0! '. – thst
Ciao Jay, ho provato il tuo codice ora a casa e ha funzionato bene. Ho usato JDK 1.8.044 e proverò .77 e .91 (attualmente in download). Non ho potuto scaricare .76 per Windows però. Hai controllato l'aggiornamento di Java? Questo succede solo nell'emulatore Android? – thst