import java.util.*; class AdvancedArrayAccess { private static final int[] LENGTH = {0, 10, 20, 30}; private static final int[] LENGTH2 = {0, 10, 20, 30}; private static final String[] ARRAY = new String[] {"xyz".toLowerCase(Locale.ENGLISH)}; void testInstanceOf() { Object[] arr = {new String("foo"), new Integer(0)}; if(arr[0] instanceof Number) { System.out.println(((Number)arr[0]).intValue()); } } void testStaticFinal() { if(LENGTH[2] == 20) { System.out.println("ok"); } } void testAny(int i) { if(LENGTH[i] > 30) { System.out.println("Impossible"); } if(LENGTH[i] > 20) { System.out.println("Possible"); } if(i < 3 && LENGTH[i] > 20) { System.out.println("Impossible"); } } void testCall(int i) { if(ARRAY[i] == null) { System.out.println("Impossible"); } } int[] getLengths() { // array is still read-only return LENGTH.clone(); } int getLengthsCount() { // array is still read-only return LENGTH.length; } int[] getLength2() { // Reference leaks: do not consider an array as read-only return LENGTH2; } void testStaticFinal(int idx) { if(idx == 2 && LENGTH[idx] == 20) { System.out.println("ok"); } } void testStaticFinalRW(int idx) { if(idx == 2 && LENGTH2[idx] == 20) { System.out.println("ok"); } } void testWrite(int[] arr, int idx) { if(idx != 0) return; arr[idx] = 10; if(arr[0] == 11) { System.out.println("impossible"); } } void testSplitState(boolean b, String[] data) { data[1] = "A"; data[2] = "B"; int idx = b ? 0 : 1; data[idx] = "C"; if(data[2].equals("D")) { System.out.println("never"); } if(data[1].equals("E")) { System.out.println("never"); } if(data[1].equals("A") && b) { System.out.println("Only if b is true"); } } // Should not be too complex static int max(float[] array) { int max = 0; float val = array[0]; for (int i = 1; i < array.length; i++) { if (val < array[i]) { max = i; val = array[i]; } } return max; } void processArray(String[] arr) { for(int i=0; itrim()); } } final String[] getData() { return new String[] {"a", "b", "c"}; } void testConditional(String[] arr, int idx) { if(idx == 0) { arr[idx] = "foo"; } if(arr[0].equals("bar") && idx == 0) { System.out.println("never"); } } void testLocalRewritten() { String[] arr = {"foo", "bar", "baz"}; arr[0] = "qux"; int result = 0; if(arr[1].equals("bar")) { result = 1; } if(arr[2].equals("bar")) { result = 1; } if(arr[0].equals("foo")) { result = 2; } System.out.println(result); arr = new String[] {"bar", "baz", "foo"}; arr[2] = "qux"; if(arr[1].equals("bar")) { result = 2; } if(arr[2].equals("qux")) { result = 1; } if(arr[0].equals("bar")) { result = 2; } System.out.println(result); } void testObjectVar() { Object x; x = new String[] {"foo", "bar"}; if(((String[])x)[0].equals("foo")) { System.out.println("Not supported if variable type is not array"); } } void testWidening(byte[] b, int idx) { int i = b[idx] & 0xFF; if(i > 255) { System.out.println("Impossible"); } } void testNonInitializedShort() { int[] x = new int[2]; if(x[0] == 0) { System.out.println("Always"); } } void testFor2() { String[] x = new String[2]; for (int i = 0; i < 2; i++) { x[i] = String.valueOf(i); } for (int i = 0; i < 2; i++) { System.out.println(x[i].trim()); } } void testFor3() { int[] x = new int[3]; for (int i = 0; i < 3; i++) { x[i] = i; } if(x[2] == 2) { System.out.println("Always"); } } int[] getArray() { return new int[0]; } void testInitializerWrong() { getArray() = {1,2,3}; } void testLongInitializer() { int[] arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40}; arr[0] = 1; if(arr[20] == 20) {} if(arr[31] == 31) {} // Too long initializers aren't tracked for mutable arrays if(arr[32] == 32) {} if(arr[33] == 33) {} int[] arr2 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40}; if(arr2[20] == 20) {} if(arr2[31] == 31) {} // ..but tracked for immutable arrays if(arr2[32] == 32) {} if(arr2[33] == 33) {} } private static void change(Object[] x) { ((String[]) x[0])[0] = "OK"; } // IDEA-210027 public static void main(String[] args) { String[] array = new String[] { null }; change(new Object[] { array }); System.out.println(array[0]); // <-- Value 'array[0]' was reported as always 'null' } }