| /* | |
| * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| /** | |
| * @test | |
| * @bug 8277451 | |
| * @run testng NegativeTest | |
| * @summary Test exception thrown due to bad receiver and bad value on | |
| * Field with and without setAccessible(true) | |
| */ | |
| import java.lang.reflect.Field; | |
| import java.lang.reflect.Modifier; | |
| import org.testng.annotations.DataProvider; | |
| import org.testng.annotations.Test; | |
| import static org.testng.Assert.*; | |
| public class NegativeTest { | |
| static class Fields { | |
| public static int si; | |
| public static char sc; | |
| public static byte sb; | |
| public static short ss; | |
| public static long sl; | |
| public static double sd; | |
| public static float sf; | |
| public static boolean sz; | |
| public static String so; | |
| public static final int sfi = 10; | |
| public static final char sfc = 'a'; | |
| public static final byte sfb = 1; | |
| public static final short sfs = 2; | |
| public static final long sfl = 1000L; | |
| public static final double sfd = 1.0; | |
| public static final float sff = 2.0f; | |
| public static final boolean sfz = true; | |
| public static final String sfo = "abc"; | |
| public int i; | |
| public char c; | |
| public byte b; | |
| public short s; | |
| public long l; | |
| public double d; | |
| public float f; | |
| public boolean z; | |
| public String o; | |
| public final int fi = 10; | |
| public final char fc = 'a'; | |
| public final byte fb = 1; | |
| public final short fs = 2; | |
| public final long fl = 1000L; | |
| public final double fd = 1.0; | |
| public final float ff = 2.0f; | |
| public final boolean fz = true; | |
| public final String fo = "abc"; | |
| } | |
| static final Field i_field = field("i", false); | |
| static final Field c_field = field("c", false); | |
| static final Field b_field = field("b", false); | |
| static final Field s_field = field("s", false); | |
| static final Field l_field = field("l", false); | |
| static final Field d_field = field("d", false); | |
| static final Field f_field = field("f", false); | |
| static final Field z_field = field("z", false); | |
| static final Field o_field = field("o", false); | |
| static final Field fi_field = field("fi", false); | |
| static final Field fc_field = field("fc", false); | |
| static final Field fb_field = field("fb", false); | |
| static final Field fs_field = field("fs", false); | |
| static final Field fl_field = field("fl", false); | |
| static final Field fd_field = field("fd", false); | |
| static final Field ff_field = field("ff", false); | |
| static final Field fz_field = field("fz", false); | |
| static final Field fo_field = field("fo", false); | |
| static final Field override_i_field = field("i", true); | |
| static final Field override_c_field = field("c", true); | |
| static final Field override_b_field = field("b", true); | |
| static final Field override_s_field = field("s", true); | |
| static final Field override_l_field = field("l", true); | |
| static final Field override_d_field = field("d", true); | |
| static final Field override_f_field = field("f", true); | |
| static final Field override_z_field = field("z", true); | |
| static final Field override_o_field = field("o", true); | |
| static final Field override_fi_field = field("fi", true); | |
| static final Field override_fc_field = field("fc", true); | |
| static final Field override_fb_field = field("fb", true); | |
| static final Field override_fs_field = field("fs", true); | |
| static final Field override_fl_field = field("fl", true); | |
| static final Field override_fd_field = field("fd", true); | |
| static final Field override_ff_field = field("ff", true); | |
| static final Field override_fz_field = field("fz", true); | |
| static final Field override_fo_field = field("fo", true); | |
| static final Field si_field = field("si", false); | |
| static final Field sc_field = field("sc", false); | |
| static final Field sb_field = field("sb", false); | |
| static final Field ss_field = field("ss", false); | |
| static final Field sl_field = field("sl", false); | |
| static final Field sd_field = field("sd", false); | |
| static final Field sf_field = field("sf", false); | |
| static final Field sz_field = field("sz", false); | |
| static final Field so_field = field("so", false); | |
| static final Field sfi_field = field("sfi", false); | |
| static final Field sfc_field = field("sfc", false); | |
| static final Field sfb_field = field("sfb", false); | |
| static final Field sfs_field = field("sfs", false); | |
| static final Field sfl_field = field("sfl", false); | |
| static final Field sfd_field = field("sfd", false); | |
| static final Field sff_field = field("sff", false); | |
| static final Field sfz_field = field("sfz", false); | |
| static final Field sfo_field = field("sfo", false); | |
| static final Field override_si_field = field("si", true); | |
| static final Field override_sc_field = field("sc", true); | |
| static final Field override_sb_field = field("sb", true); | |
| static final Field override_ss_field = field("ss", true); | |
| static final Field override_sl_field = field("sl", true); | |
| static final Field override_sd_field = field("sd", true); | |
| static final Field override_sf_field = field("sf", true); | |
| static final Field override_sz_field = field("sz", true); | |
| static final Field override_so_field = field("so", true); | |
| static final Field override_sfi_field = field("sfi", true); | |
| static final Field override_sfc_field = field("sfc", true); | |
| static final Field override_sfb_field = field("sfb", true); | |
| static final Field override_sfs_field = field("sfs", true); | |
| static final Field override_sfl_field = field("sfl", true); | |
| static final Field override_sfd_field = field("sfd", true); | |
| static final Field override_sff_field = field("sff", true); | |
| static final Field override_sfz_field = field("sfz", true); | |
| static final Field override_sfo_field = field("sfo", true); | |
| private static Field field(String name, boolean suppressAccessCheck) { | |
| try { | |
| Field f = Fields.class.getDeclaredField(name); | |
| if (suppressAccessCheck) { | |
| f.setAccessible(true); | |
| } | |
| return f; | |
| } catch (ReflectiveOperationException e) { | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| @DataProvider(name = "instanceFields") | |
| private Object[][] instanceFields() { | |
| return new Object[][]{ | |
| new Object[]{i_field}, | |
| new Object[]{c_field}, | |
| new Object[]{b_field}, | |
| new Object[]{s_field}, | |
| new Object[]{l_field}, | |
| new Object[]{d_field}, | |
| new Object[]{f_field}, | |
| new Object[]{z_field}, | |
| new Object[]{o_field}, | |
| new Object[]{override_i_field}, | |
| new Object[]{override_c_field}, | |
| new Object[]{override_b_field}, | |
| new Object[]{override_s_field}, | |
| new Object[]{override_l_field}, | |
| new Object[]{override_d_field}, | |
| new Object[]{override_f_field}, | |
| new Object[]{override_z_field}, | |
| new Object[]{override_o_field}, | |
| // final instance fields | |
| new Object[]{fi_field}, | |
| new Object[]{fc_field}, | |
| new Object[]{fb_field}, | |
| new Object[]{fs_field}, | |
| new Object[]{fl_field}, | |
| new Object[]{fd_field}, | |
| new Object[]{ff_field}, | |
| new Object[]{fz_field}, | |
| new Object[]{fo_field}, | |
| new Object[]{override_fi_field}, | |
| new Object[]{override_fc_field}, | |
| new Object[]{override_fb_field}, | |
| new Object[]{override_fs_field}, | |
| new Object[]{override_fl_field}, | |
| new Object[]{override_fd_field}, | |
| new Object[]{override_ff_field}, | |
| new Object[]{override_fz_field}, | |
| new Object[]{override_fo_field}, | |
| }; | |
| } | |
| private static Fields INSTANCE = new Fields(); | |
| /* | |
| * Test Field::get on a good receiver, a bad receiver and null. | |
| * | |
| * IllegalArgumentException is thrown if the receiver is of | |
| * a bad type. NullPointerException is thrown if the receiver is null. | |
| */ | |
| @Test(dataProvider = "instanceFields") | |
| public void testReceiver(Field f) throws ReflectiveOperationException { | |
| f.get(INSTANCE); // good receiver | |
| testBadReceiver(f); | |
| testNullReceiver(f); | |
| } | |
| /* | |
| * IllegalArgumentException should be thrown for bad receiver type | |
| */ | |
| private void testBadReceiver(Field f) throws ReflectiveOperationException { | |
| assertFalse(Modifier.isStatic(f.getModifiers())); // instance field | |
| Object badObj = new NegativeTest(); | |
| try { | |
| f.get(badObj); | |
| fail("expected IllegalArgumentException"); | |
| } catch (IllegalArgumentException e) { | |
| // expected | |
| } | |
| Class<?> fType = f.getType(); | |
| if (fType.isPrimitive()) { | |
| try { | |
| switch (fType.descriptorString()) { | |
| case "B" -> f.getByte(badObj); | |
| case "C" -> f.getChar(badObj); | |
| case "D" -> f.getDouble(badObj); | |
| case "F" -> f.getFloat(badObj); | |
| case "I" -> f.getInt(badObj); | |
| case "J" -> f.getLong(badObj); | |
| case "S" -> f.getShort(badObj); | |
| case "Z" -> f.getBoolean(badObj); | |
| } | |
| fail("expected IllegalArgumentException"); | |
| } catch (IllegalArgumentException e) { | |
| // expected | |
| } | |
| } | |
| } | |
| /* | |
| * NullPointerException should be thrown for null receiver | |
| */ | |
| private void testNullReceiver(Field f) throws ReflectiveOperationException { | |
| assertFalse(Modifier.isStatic(f.getModifiers())); // instance field | |
| try { | |
| f.get(null); | |
| fail("expected NullPointerException"); | |
| } catch (NullPointerException e) { | |
| // expected | |
| } | |
| Class<?> fType = f.getType(); | |
| if (fType.isPrimitive()) { | |
| try { | |
| switch (fType.descriptorString()) { | |
| case "B" -> f.getByte(null); | |
| case "C" -> f.getChar(null); | |
| case "D" -> f.getDouble(null); | |
| case "F" -> f.getFloat(null); | |
| case "I" -> f.getInt(null); | |
| case "J" -> f.getLong(null); | |
| case "S" -> f.getShort(null); | |
| case "Z" -> f.getBoolean(null); | |
| } | |
| fail("expected NullPointerException"); | |
| } catch (NullPointerException e) { | |
| // expected | |
| } | |
| } | |
| } | |
| @DataProvider(name = "writeableFields") | |
| private Object[][] writeableFields() { | |
| Fields obj = new Fields(); | |
| return new Object[][]{ | |
| // instance fields with and without setAccessible(true) | |
| new Object[]{i_field, obj, Integer.valueOf(10)}, | |
| new Object[]{c_field, obj, Character.valueOf('c')}, | |
| new Object[]{b_field, obj, Byte.valueOf((byte)1)}, | |
| new Object[]{s_field, obj, Short.valueOf((short)2)}, | |
| new Object[]{l_field, obj, Long.valueOf(1000)}, | |
| new Object[]{d_field, obj, Double.valueOf(1.2)}, | |
| new Object[]{f_field, obj, Float.valueOf(2.5f)}, | |
| new Object[]{z_field, obj, Boolean.valueOf(true)}, | |
| new Object[]{o_field, obj, "good-value"}, | |
| new Object[]{override_i_field, obj, Integer.valueOf(10)}, | |
| new Object[]{override_c_field, obj, Character.valueOf('c')}, | |
| new Object[]{override_b_field, obj, Byte.valueOf((byte)1)}, | |
| new Object[]{override_s_field, obj, Short.valueOf((short)2)}, | |
| new Object[]{override_l_field, obj, Long.valueOf(1000)}, | |
| new Object[]{override_d_field, obj, Double.valueOf(1.2)}, | |
| new Object[]{override_f_field, obj, Float.valueOf(2.5f)}, | |
| new Object[]{override_z_field, obj, Boolean.valueOf(true)}, | |
| new Object[]{override_o_field, obj, "good-value"}, | |
| // instance final fields with setAccessible(true) | |
| new Object[]{override_fi_field, obj, Integer.valueOf(10)}, | |
| new Object[]{override_fc_field, obj, Character.valueOf('c')}, | |
| new Object[]{override_fb_field, obj, Byte.valueOf((byte)1)}, | |
| new Object[]{override_fs_field, obj, Short.valueOf((short)2)}, | |
| new Object[]{override_fl_field, obj, Long.valueOf(1000)}, | |
| new Object[]{override_fd_field, obj, Double.valueOf(1.2)}, | |
| new Object[]{override_ff_field, obj, Float.valueOf(2.5f)}, | |
| new Object[]{override_fz_field, obj, Boolean.valueOf(true)}, | |
| new Object[]{override_fo_field, obj, "good-value"}, | |
| // static fields with and without setAccessible(true) | |
| new Object[]{si_field, null, Integer.valueOf(10)}, | |
| new Object[]{sc_field, null, Character.valueOf('c')}, | |
| new Object[]{sb_field, null, Byte.valueOf((byte)1)}, | |
| new Object[]{ss_field, null, Short.valueOf((short)2)}, | |
| new Object[]{sl_field, null, Long.valueOf(1000)}, | |
| new Object[]{sd_field, null, Double.valueOf(1.2)}, | |
| new Object[]{sf_field, null, Float.valueOf(2.5f)}, | |
| new Object[]{sz_field, null, Boolean.valueOf(true)}, | |
| new Object[]{so_field, null, "good-value"}, | |
| new Object[]{override_si_field, null, Integer.valueOf(10)}, | |
| new Object[]{override_sc_field, null, Character.valueOf('c')}, | |
| new Object[]{override_sb_field, null, Byte.valueOf((byte)1)}, | |
| new Object[]{override_ss_field, null, Short.valueOf((short)2)}, | |
| new Object[]{override_sl_field, null, Long.valueOf(1000)}, | |
| new Object[]{override_sd_field, null, Double.valueOf(1.2)}, | |
| new Object[]{override_sf_field, null, Float.valueOf(2.5f)}, | |
| new Object[]{override_sz_field, null, Boolean.valueOf(true)}, | |
| new Object[]{override_so_field, null, "good-value"}, | |
| }; | |
| } | |
| /* | |
| * Test Field::set with a good and bad value. | |
| * Test setting to null if the field type is primitive. | |
| * | |
| * IllegalArgumentException is thrown if the value is of a bad type or null. | |
| * NullPointerException is thrown if the receiver of an instance field is null. | |
| * The receiver is checked | |
| */ | |
| @Test(dataProvider = "writeableFields") | |
| public void testSetValue(Field f, Object obj, Object value) throws IllegalAccessException { | |
| f.set(obj, value); | |
| Class<?> fType = f.getType(); | |
| if (fType.isPrimitive()) { | |
| switch (fType.descriptorString()) { | |
| case "B" -> f.setByte(obj, ((Byte) value).byteValue()); | |
| case "C" -> f.setChar(obj, ((Character) value).charValue()); | |
| case "D" -> f.setDouble(obj, ((Double) value).doubleValue()); | |
| case "F" -> f.setFloat(obj, ((Float) value).floatValue()); | |
| case "I" -> f.setInt(obj, ((Integer) value).intValue()); | |
| case "J" -> f.setLong(obj, ((Long) value).longValue()); | |
| case "S" -> f.setShort(obj, ((Short) value).shortValue()); | |
| case "Z" -> f.setBoolean(obj, ((Boolean) value).booleanValue()); | |
| } | |
| // test null value only if it's primitive type | |
| try { | |
| f.set(obj, null); | |
| fail("expected IllegalArgumentException"); | |
| } catch (IllegalArgumentException e) { | |
| // expected | |
| } | |
| } | |
| Object badValue = new NegativeTest(); | |
| try { | |
| f.set(obj, badValue); | |
| fail("expected IllegalArgumentException"); | |
| } catch (IllegalArgumentException e) { | |
| // expected | |
| } | |
| } | |
| @DataProvider(name = "readOnlyFinalFields") | |
| private Object[][] readOnlyFinalFields() { | |
| Object obj = INSTANCE; | |
| return new Object[][]{ | |
| // instance final fields | |
| new Object[]{fi_field, obj, Integer.valueOf(10)}, | |
| new Object[]{fc_field, obj, Character.valueOf('c')}, | |
| new Object[]{fb_field, obj, Byte.valueOf((byte)1)}, | |
| new Object[]{fs_field, obj, Short.valueOf((short)2)}, | |
| new Object[]{fl_field, obj, Long.valueOf(1000)}, | |
| new Object[]{fd_field, obj, Double.valueOf(1.2)}, | |
| new Object[]{ff_field, obj, Float.valueOf(2.5f)}, | |
| new Object[]{fz_field, obj, Boolean.valueOf(true)}, | |
| new Object[]{fo_field, obj, "good-value"}, | |
| // static final fields | |
| new Object[]{sfi_field, null, Integer.valueOf(10)}, | |
| new Object[]{sfc_field, null, Character.valueOf('c')}, | |
| new Object[]{sfb_field, null, Byte.valueOf((byte)1)}, | |
| new Object[]{sfs_field, null, Short.valueOf((short)2)}, | |
| new Object[]{sfl_field, null, Long.valueOf(1000)}, | |
| new Object[]{sfd_field, null, Double.valueOf(1.2)}, | |
| new Object[]{sff_field, null, Float.valueOf(2.5f)}, | |
| new Object[]{sfz_field, null, Boolean.valueOf(true)}, | |
| new Object[]{sfo_field, null, "good-value"}, | |
| new Object[]{override_sfi_field, null, Integer.valueOf(10)}, | |
| new Object[]{override_sfc_field, null, Character.valueOf('c')}, | |
| new Object[]{override_sfb_field, null, Byte.valueOf((byte)1)}, | |
| new Object[]{override_sfs_field, null, Short.valueOf((short)2)}, | |
| new Object[]{override_sfl_field, null, Long.valueOf(1000)}, | |
| new Object[]{override_sfd_field, null, Double.valueOf(1.2)}, | |
| new Object[]{override_sff_field, null, Float.valueOf(2.5f)}, | |
| new Object[]{override_sfz_field, null, Boolean.valueOf(true)}, | |
| new Object[]{override_sfo_field, null, "good-value"}, | |
| }; | |
| } | |
| /* | |
| * Test Field::set on a read-only final field. | |
| * IllegalAccessException is thrown regardless of whether the value | |
| * is of a bad type or not. | |
| */ | |
| @Test(dataProvider = "readOnlyFinalFields") | |
| public void testSetValueOnFinalField(Field f, Object obj, Object value) { | |
| assertTrue(Modifier.isFinal(f.getModifiers())); | |
| try { | |
| f.set(obj, value); | |
| fail("expected IllegalAccessException"); | |
| } catch (IllegalAccessException e) { | |
| // expected | |
| } | |
| Class<?> fType = f.getType(); | |
| if (fType.isPrimitive()) { | |
| try { | |
| switch (fType.descriptorString()) { | |
| case "B" -> f.setByte(obj, ((Byte)value).byteValue()); | |
| case "C" -> f.setChar(obj, ((Character)value).charValue()); | |
| case "D" -> f.setDouble(obj, ((Double)value).doubleValue()); | |
| case "F" -> f.setFloat(obj, ((Float)value).floatValue()); | |
| case "I" -> f.setInt(obj, ((Integer)value).intValue()); | |
| case "J" -> f.setLong(obj, ((Long)value).longValue()); | |
| case "S" -> f.setShort(obj, ((Short)value).shortValue()); | |
| case "Z" -> f.setBoolean(obj, ((Boolean)value).booleanValue()); | |
| } | |
| fail("expected IllegalAccessException"); | |
| } catch (IllegalAccessException e) { | |
| // expected | |
| } | |
| // test null value only if it's primitive type | |
| try { | |
| f.set(obj, null); | |
| fail("expected IllegalAccessException"); | |
| } catch (IllegalAccessException e) { | |
| // expected | |
| } | |
| } | |
| Object badValue = new NegativeTest(); | |
| try { | |
| f.set(obj, badValue); | |
| fail("expected IllegalAccessException"); | |
| } catch (IllegalAccessException e) { | |
| // expected | |
| } | |
| } | |
| @DataProvider(name = "finalInstanceFields") | |
| private Object[][] finalInstanceFields() { | |
| return new Object[][]{ | |
| new Object[]{fi_field, Integer.valueOf(10)}, | |
| new Object[]{fc_field, Character.valueOf('c')}, | |
| new Object[]{fb_field, Byte.valueOf((byte) 1)}, | |
| new Object[]{fs_field, Short.valueOf((short) 2)}, | |
| new Object[]{fl_field, Long.valueOf(1000)}, | |
| new Object[]{fd_field, Double.valueOf(1.2)}, | |
| new Object[]{ff_field, Float.valueOf(2.5f)}, | |
| new Object[]{fz_field, Boolean.valueOf(true)}, | |
| new Object[]{fo_field, "good-value"}, | |
| }; | |
| } | |
| /* | |
| * Test Field::set on a final instance field with either a bad receiver | |
| * or null. IllegalArgumentException is thrown if the receiver is of | |
| * a bad type. NullPointerException is thrown if the receiver is null. | |
| * The receiver is checked before the access check is performed and | |
| * also before the value is checked. | |
| */ | |
| @Test(dataProvider = "finalInstanceFields") | |
| public void testReceiverOnFinalField(Field f, Object value) { | |
| assertTrue(Modifier.isFinal(f.getModifiers())); | |
| Object badReceiver = new NegativeTest(); | |
| // set the field with a bad receiver with a good value | |
| try { | |
| f.set(badReceiver, value); | |
| fail("expected IllegalArgumentException"); | |
| } catch (IllegalArgumentException e) { | |
| // expected | |
| } catch (IllegalAccessException e) { | |
| throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e); | |
| } | |
| // set the field with a bad receiver with a bad value | |
| Object badValue = new NegativeTest(); | |
| try { | |
| f.set(badReceiver, badValue); | |
| fail("expected IllegalArgumentException"); | |
| } catch (IllegalArgumentException e) { | |
| // expected | |
| } catch (IllegalAccessException e) { | |
| throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e); | |
| } | |
| // set the field with a null receiver with a good value | |
| try { | |
| f.set(null, value); | |
| fail("expected NullPointerException"); | |
| } catch (NullPointerException e) { | |
| // expected | |
| } catch (IllegalAccessException e) { | |
| throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e); | |
| } | |
| // set the field with a null receiver with a bad value | |
| try { | |
| f.set(null, badValue); | |
| fail("expected NullPointerException"); | |
| } catch (NullPointerException e) { | |
| // expected | |
| } catch (IllegalAccessException e) { | |
| throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e); | |
| } | |
| Class<?> fType = f.getType(); | |
| if (fType.isPrimitive()) { | |
| // test bad receiver | |
| try { | |
| switch (fType.descriptorString()) { | |
| case "B" -> f.setByte(badReceiver, ((Byte) value).byteValue()); | |
| case "C" -> f.setChar(badReceiver, ((Character) value).charValue()); | |
| case "D" -> f.setDouble(badReceiver, ((Double) value).doubleValue()); | |
| case "F" -> f.setFloat(badReceiver, ((Float) value).floatValue()); | |
| case "I" -> f.setInt(badReceiver, ((Integer) value).intValue()); | |
| case "J" -> f.setLong(badReceiver, ((Long) value).longValue()); | |
| case "S" -> f.setShort(badReceiver, ((Short) value).shortValue()); | |
| case "Z" -> f.setBoolean(badReceiver, ((Boolean) value).booleanValue()); | |
| } | |
| } catch (IllegalArgumentException e) { | |
| } catch (IllegalAccessException e) { | |
| throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e); | |
| } | |
| // test null receiver | |
| try { | |
| switch (fType.descriptorString()) { | |
| case "B" -> f.setByte(null, ((Byte) value).byteValue()); | |
| case "C" -> f.setChar(null, ((Character) value).charValue()); | |
| case "D" -> f.setDouble(null, ((Double) value).doubleValue()); | |
| case "F" -> f.setFloat(null, ((Float) value).floatValue()); | |
| case "I" -> f.setInt(null, ((Integer) value).intValue()); | |
| case "J" -> f.setLong(null, ((Long) value).longValue()); | |
| case "S" -> f.setShort(null, ((Short) value).shortValue()); | |
| case "Z" -> f.setBoolean(null, ((Boolean) value).booleanValue()); | |
| } | |
| } catch (NullPointerException e) { | |
| // expected | |
| } catch (IllegalAccessException e) { | |
| throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e); | |
| } | |
| } | |
| } | |
| } |