سؤال

وأنا أبحث لتنفيذ شيء في جاوة على غرار:

class Foo{
 private int lorem; //
 private int ipsum;      

 public setAttribute(String attr, int val){
  //sets attribute based on name
 }

 public static void main(String [] args){
  Foo f = new Foo();
  f.setAttribute("lorem",1);
  f.setAttribute("ipsum",2);
 }

 public Foo(){}
}

... حيث يتم تعيين متغير استنادا إلى اسم متغير بدون أسماء المتغيرات الثابت تلوينها ودون استخدام أي هياكل البيانات الأخرى. هل هذا ممكن؟

هل كانت مفيدة؟

المحلول

وهنا هو كيف يمكن تنفيذ setAttribute باستخدام الانعكاس (لقد سميت وظيفة، وهناك وظائف انعكاس مختلفة لأنواع الحقول مختلفة):

public void setIntField(String fieldName, int value)
        throws NoSuchFieldException, IllegalAccessException {
    Field field = getClass().getDeclaredField(fieldName);
    field.setInt(this, value);
}

نصائح أخرى

في عام، كنت تريد استخدام التأمل. هنا هو مقدمة جيدة لفي الموضوع مع أمثلة

وعلى وجه الخصوص، يصف القسم "تغيير قيم الحقول" كيفية القيام بما تريد القيام به.

وألاحظ أن يقول المؤلف: "هذه الميزة هي قوية للغاية وليس لديها ما يعادلها في اللغات التقليدية الأخرى." وبطبيعة الحال، في السنوات العشر الأخيرة (كتب المقال في عام 1998) رأينا التقدم الكبير في اللغات الديناميكية. ويتم ذلك ما سبق بسهولة إلى حد ما في بيرل، بيثون، PHP، روبي، وهلم جرا. وأظن أن هذا هو الاتجاه الذي قد يأتي من يقوم على سمة "حدة التقييم".

وأيضا، نلقي نظرة على BeanUtils حيث يمكن إخفاء بعض من تعقيد باستخدام الانعكاس من لك.

والسؤال هو محدد ل[إينتس]، وهو أمر مفيد، ولكن هنا شيئا قليلا أكثر عمومية. هذا النوع من الأسلوب مفيدا إذا كنت تقوم بتحميل في التمثيل String حقل أزواج اسم / قيمة الحقل.

import java.lang.reflect.Field;

public class FieldTest {

    static boolean isValid = false;
    static int count = 5;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        FieldTest test = new FieldTest();
        test.setProperty("count", "24");
        System.out.println(count);
        test.setProperty("isValid", "true");
        System.out.println(isValid);
    }

    public void setProperty(String fieldName, String value) throws NoSuchFieldException, IllegalAccessException {
        Field field = this.getClass().getDeclaredField(fieldName);
        if (field.getType() == Character.TYPE) {field.set(getClass(), value.charAt(0)); return;}
        if (field.getType() == Short.TYPE) {field.set(getClass(), Short.parseShort(value)); return;}
        if (field.getType() == Integer.TYPE) {field.set(getClass(), Integer.parseInt(value)); return;}
        if (field.getType() == Long.TYPE) {field.set(getClass(), Long.parseLong(value)); return;}
        if (field.getType() == Float.TYPE) {field.set(getClass(), Float.parseFloat(value)); return;}
        if (field.getType() == Double.TYPE) {field.set(getClass(), Double.parseDouble(value)); return;}
        if (field.getType() == Byte.TYPE) {field.set(getClass(), Byte.parseByte(value)); return;}
        if (field.getType() == Boolean.TYPE) {field.set(getClass(), Boolean.parseBoolean(value)); return;}
        field.set(getClass(), value);
    }

}

واعتمادا على الاستخدام، يمكنك استخدام انعكاس كما نصحت أعلاه، أو ربما HashMap سيكون أكثر ملاءمة ...

وقد ترغب في تخزين بعض البيانات انعكاس بينما كنت في ذلك:

import java.lang.reflect.Field;
import java.util.HashMap;

class Foo {
    private HashMap<String, Field> fields = new HashMap<String, Field>();

    private void setAttribute(Field field, Object value) {
        field.set(this, value);
    }

    public void setAttribute(String fieldName, Object value) {
        if (!fields.containsKey(fieldName)) {
            fields.put(fieldName, value);
        }
        setAttribute(fields.get(fieldName), value);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top