简体   繁体   English

Java - 我可以将变量修改从一个类转换为另一个类吗?

[英]Java - Can I cast a variable modification from one class to another?

Say I have in class A : 说我在A班:

int a = 1, b = 2, c = 3;

Now, say in class B I have a function: 现在,在B级说我有一个功能:

public int void reset(String intName, A classA) {
...
}

Within reset() if I do reset('c', classA) , then I want c in classA to be reset. reset()如果我reset('c', classA) ,那么我希望重置classA c If I do a reset('b', classA) , then I want b in classA to be reset and so forth. 如果我进行reset('b', classA) ,那么我希望重置classA b等等。 I'm not sure if this is possible, but I need this to kill off units of different classes in a game. 我不确定这是否可行,但我需要这个来消灭游戏中不同类别的单位。

This is possible through reflection. 这可以通过反思来实现。 But since reflection is slow, I advise you not to try reflection immediately. 但由于反思很慢,我建议你不要立即尝试反思。 Try something else first. 先尝试别的。 Why can't you just do: 你为什么不能这样做:

someObjectOfA.a = some value;
someObjectOfA.b = some value;
someObjectOfA.c = some value;

Anyway, here is the solution using reflection: 无论如何,这是使用反射的解决方案:

public static void reset(String name, A a) throws NoSuchFieldException, IllegalAccessException {
    Class<A> clazz = A.class;
    Field f = clazz.getField(name);
    f.set(a, 0);
}

Note that a , b and c must be declared public or a NoSuchFieldException will be thrown. 请注意,必须将abc声明为publicNoSuchFieldException将抛出NoSuchFieldException

If you don't want to expose your fields, you can add setters like this one: 如果您不想公开字段,可以添加如下设置:

public void setA(Integer value) {
    a = value;
}

Then the reset method will be: 然后reset方法将是:

public static void reset(String name, A a) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    Class<A> clazz = A.class;
    Method m = clazz.getMethod("set" + name.toUpperCase(), Integer.class);
    m.invoke(a, 0);
}

There are many options here, even without using reflection (ie dynamically modifying arbitrary properties of the object by names specified at runtime). 这里有很多选项,即使不使用反射(即通过运行时指定的名称动态修改对象的任意属性)。 The simplest is to simply have A be responsible for translating from the specified key to the corresponding variable: 最简单的是让A负责从指定的键转换为相应的变量:

public class A {
    private static int a = 1, b = 2, c = 3;

    public void reset(String key) {
        switch(key) {
        case "a": a = 0;
                  break;
        case "b": b = 0;
                  break;
        case "c": c = 0;
                  break;
        default:
                  break;
        }
    }
}

public class B {
    public int void reset(String intName, A obj) {
        obj.reset(intName);
    }
}

This leads to repetitive code though, and it's easy to make mistakes, especially as you add new fields to A . 这会导致重复的代码,并且很容易出错,尤其是当您向A添加新字段时。


A better option would be using a Map to dynamically map the property names to their values: 更好的选择是使用Map将属性名称动态映射到它们的值:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class A {
    private static Map<String, Integer> map = new HashMap<>();
    static {
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);
    }

    public Map<String, Integer> getGameProperties() {
        return Collections.unmodifiableMap(map);
    }

    public void reset(String key) {
        map.put(key, 0);
    }
}

public class B {
    public int void reset(String intName, A obj) {
        obj.reset(intName);
    }
}

This handles the property declaration and key mapping in a single step, so that fixes the issue of the repetitive, error-prone code. 它在一个步骤中处理属性声明和键映射,从而修复了重复的,容易出错的代码的问题。 It does potentially affect the external interface of the class now since you got rid of the individual fields and replaced them with a Map . 它现在可能会影响类的外部接口,因为您删除了各个字段并将其替换为Map That's of course a good reason to keep your fields private and use getters/setters instead, since getters can be updated to look at a Map without changing the external API of class A . 这当然是保持字段private并使用getter / setter的一个很好的理由,因为可以更新getter以查看Map而无需更改A类的外部API。

I would design my class A like this: 我会像这样设计我的A班:

class A
{
   public enum UnitType { TANK, TRIKE, COMMANDO };

   public void reset (UnitType type); 

   //or even:
   public void reset (Set<UnitType> types); 

}

So class B could call: 所以B级可以打电话:

a.reset(UnitType.TANK);

or in the Set case 或者在Set情况下

a.reset(EnumSet.of(UnitType.TANK, UnitType.COMMANDO));

or 要么

a.reset(EnumSet.allOf(UnitType.class));

You can still choose in class A how to keep track of the counts, without influencing the interface to class B 您仍然可以在class A选择如何跟踪计数,而不会影响到class B的接口

For example, class A can use a Map internally to keep track of the counts (which seems a good idea), but also fields, or any other method. 例如,A类可以在内部使用Map来跟踪计数(这似乎是一个好主意),但也可以使用字段或任何其他方法。

Why not just to have a something like setter in class A if you really want to reset it from other class? 如果你真的想从其他类中重置它,为什么不在A类中设置类似setter的东西呢?

Say I have in class A: 说我在A班:

int a = 1, b = 2, c = 3;

public void resetA()
{
    this.a = 0;
}
public void resetB()
{
    this.b = 0;
}
public void resetC()
{
    this.c = 0;
}

or 要么

int a = 1, b = 2, c = 3;

public void resetAll()
{
    this.c = 0;
    this.a = 0;
    this.b = 0;
}

i just can't think for now how to make a good coding for it's flexibility but it can reset you're value even from the other class if you like 我现在想不出如何为它的灵活性做出良好的编码,但如果你愿意,它可以重置你的价值

Try this. 尝试这个。 No need to write setter method for each field. 无需为每个字段编写setter方法。

        try
        {
            Field field = classA.getClass().getDeclaredField(intName);    
            field.setAccessible(true);
            Object value = field.get(classA);
            System.out.println(" val "+ value);
            field.set(classA, 0);//Reset to zero
            value = field.get(classA);
            System.out.println(" val "+ value);
        } catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java变量无法从一个类访问另一个类 - Java variable can't accesed from one class to another 如何将变量从一种方法转移到另一种方法而不将其存储在Java中的类中? - How can I transfer a variable from one method to another without storing it in a class in Java? 如何从另一个 class I Java 访问变量 - How can I acces variable from another class I Java 如何将变量从一类传递到另一类? - How can I pass a variable from one class to another? 如何使用Java中另一个类的变量 - How can I use a variable from another class in Java 如何从Java中的另一个类获取变量? - How can I get a variable from another class in Java? 在java中将变量从一个类传递到另一个类 - Passing a variable from one class to another in java 如何在Java中将变量从一类传递到另一类? - How can I pass variables from one class to another in Java? 如果我已将其声明为Java中类的成员变量,是否可以访问另一个方法中一个方法的变量值? - Can i access the value of a variable of one method in another method if i have declared it as a member variable of the class in java? 如何在一个Java类中更改另一个Java类中的变量,然后从第三个Java类访问该更改的变量? - How do I change a variable in one java class from another, then access that changed variable from a third java class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM