Repository: open-feature/java-sdk (java)

Issue:
Value.isList accepts List<Object> where only the first element is a Value
https://github.com/open-feature/java-sdk/blob/ed2e963a2a1eb59be7fa19e3a4cd1a0791c354e3/src/main/java/dev/openfeature/sdk/Value.java#L133-L137

This method `isList()` is used in constructor https://github.com/open-feature/java-sdk/blob/ed2e963a2a1eb59be7fa19e3a4cd1a0791c354e3/src/main/java/dev/openfeature/sdk/Value.java#L37 but it's checking only the first element of the list. With this check a `List<Object>` can be added if only the first element is a `Value` while the other aren't.

In my opinion this test must pass, but it fails because the exception isn't thrown
```java
@Test
public void listMustContainOnlyValues() {
    String item = "item";
    List<Object> list = new ArrayList<>();
    list.add(new Value(item));
    list.add(item);
    try {
        new Value((Object) list);
        fail("Should fail because list contains values and non-values and the exception should be thrown.");
    } catch (InstantiationException e) {
        assertEquals("Invalid value type: class java.util.ArrayList", e.getMessage());
    }
}
```
Maybe the constructor with `Object` parameter shouldn't accept lists to force the use of constructor with `List<Value>` where the list will only contain elements of type `Value` https://github.com/open-feature/java-sdk/blob/ed2e963a2a1eb59be7fa19e3a4cd1a0791c354e3/src/main/java/dev/openfeature/sdk/Value.java#L75-L77

Pull request:
fix: validate list content to be values
## This PR

Fixes #286

`Value.isList()` now validate list internal objects to be `Value` typed

Patch:
diff --git a/src/main/java/dev/openfeature/sdk/Value.java b/src/main/java/dev/openfeature/sdk/Value.java
index f4ad909..672b65c 100644
--- a/src/main/java/dev/openfeature/sdk/Value.java
+++ b/src/main/java/dev/openfeature/sdk/Value.java
@@ -125,14 +125,27 @@ public class Value implements Cloneable {
     }
     
     /** 
-     * Check if this Value represents a List.
+     * Check if this Value represents a List of Values.
      * 
      * @return boolean
      */
     public boolean isList() {
-        return this.innerObject instanceof List
-            && (((List) this.innerObject).isEmpty()
-            || ((List) this.innerObject).get(0) instanceof Value);
+        if (!(this.innerObject instanceof List)) {
+            return false;
+        }
+
+        List<?> list = (List<?>) this.innerObject;
+        if (list.isEmpty()) {
+            return true;
+        }
+
+        for (Object obj : list) {
+            if (!(obj instanceof Value)) {
+                return false;
+            }
+        }
+
+        return true;
     }
 
     /** 


Test patch:
diff --git a/src/test/java/dev/openfeature/sdk/ValueTest.java b/src/test/java/dev/openfeature/sdk/ValueTest.java
index aa6ac62..53513af 100644
--- a/src/test/java/dev/openfeature/sdk/ValueTest.java
+++ b/src/test/java/dev/openfeature/sdk/ValueTest.java
@@ -134,4 +134,12 @@ public class ValueTest {
             fail("Unexpected exception occurred.", e);
         }
     }
+
+    @Test public void valueConstructorValidateListInternals() {
+        List<Object> list = new ArrayList<>();
+        list.add(new Value("item"));
+        list.add("item");
+
+        assertThrows(InstantiationException.class, ()-> new Value(list));
+    }
 }