Java泛型交换字段无效求助:游戏按钮精灵切换场景
为什么泛型swap方法无法实现字段交换?
问题出在Java的参数传递规则上:Java里所有参数都是值传递——不管是基本类型还是引用类型,传递给方法的都是原始值的副本。
具体到你的代码分析:
当你调用swap(imgs, imgs2)时,传递给swap方法的是imgs和imgs2这两个引用的副本。在swap方法内部,你交换的只是这两个副本的指向,而类的成员变量imgs和imgs2本身(原始引用)根本没被修改。这就像你把家里的两把钥匙各复制了一份给朋友,朋友交换了手里的复制钥匙,但你手里的原始钥匙位置完全没变。
而你能正常工作的swapImage()方法,是直接操作类的成员变量本身,交换的是原始引用的指向,所以能生效。
如何封装成可用的工具类方法?
如果想把交换逻辑封装到工具类里,有几种方案:
方案1:用容器包装引用(简单直观)
通过长度为1的数组来持有引用,因为数组是对象,修改数组内的元素会影响外部:
public final class Utilities { private Utilities(){} public static <T> void swap(T[] holder1, T[] holder2){ T tmp = holder1[0]; holder1[0] = holder2[0]; holder2[0] = tmp; } }
调用方式:
public void swapImageWithUtility() { BufferedImage[] imgsHolder = {imgs}; BufferedImage[] imgs2Holder = {imgs2}; Utilities.swap(imgsHolder, imgs2Holder); imgs = imgsHolder[0]; imgs2 = imgs2Holder[0]; }
方案2:用反射(通用性强但不够类型安全)
通过反射直接操作对象的字段,适合需要通用交换任意对象字段的场景:
public final class Utilities { private Utilities(){} @SuppressWarnings("unchecked") public static <T> void swap(Object targetObj, String fieldName1, String fieldName2) throws NoSuchFieldException, IllegalAccessException { Field field1 = targetObj.getClass().getDeclaredField(fieldName1); Field field2 = targetObj.getClass().getDeclaredField(fieldName2); // 允许访问私有字段 field1.setAccessible(true); field2.setAccessible(true); T temp = (T) field1.get(targetObj); field1.set(targetObj, field2.get(targetObj)); field2.set(targetObj, temp); } }
调用方式:
public void swapImageWithReflection() { try { Utilities.swap(this, "imgs", "imgs2"); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } }
注意:反射会跳过访问权限检查,且性能略低,游戏中如果是高频调用需谨慎使用。
方案3:针对特定场景写专用方法(最适合游戏开发)
如果只是针对SpecialButton这类场景,直接写专用的工具方法反而更高效简洁:
public final class Utilities { private Utilities(){} public static void swapButtonImages(SpecialButton button) { BufferedImage[] tmp = button.imgs; button.imgs = button.imgs2; button.imgs2 = tmp; } }
调用方式:
public void swapImageWithSpecializedUtility() { Utilities.swapButtonImages(this); }
内容的提问来源于stack exchange,提问作者Ivo Heberle
相关产品推荐
相关产品推荐

