문제

나는 다음의 선을 따라 Java로 무언가를 구현하려고합니다.

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);
}

다른 팁

일반적으로 반사를 사용하고 싶습니다. 다음은 좋은 소개입니다 예제가있는 주제

특히, "필드의 변화하는 값"섹션은 원하는 일을 수행하는 방법을 설명합니다.

저자는 "이 기능은 매우 강력하고 다른 기존 언어에서는 동등한 것이 없습니다"라고 말합니다. 물론, 지난 10 년 동안 (기사는 1998 년에 작성 되었음) 우리는 역동적 인 언어로 큰 보폭을 보았습니다. 위는 Perl, Python, PHP, Ruby 등에서 상당히 쉽게 수행됩니다. 나는 이것이 "평가"태그를 기반으로 한 방향이라고 생각합니다.

또한 살펴보십시오 비누 틸 반사를 사용하는 복잡성을 숨길 수 있습니다.

문제는 Ints에만 해당되지만 도움이되지만 여기에 좀 더 일반적인 것이 있습니다. 이 유형의 방법은로드하는 경우 유용합니다. 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);
    }

}

사용법에 따라 위에서 조언 한대로 반사를 사용할 수 있거나 해시 맵이 더 적합 할 수 있습니다 ...

당신이 그것을하는 동안 일부 반사 데이터를 캐시 할 수 있습니다.

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