2017-01-24 3 views
0

Возможно ли решить следующую проблему с помощью встроенного Java API? (Я хочу, чтобы сохранить строгий частный доступ, как показано)Выделение Java Инициализация частных полей класса

  1. У меня есть п подклассов абстрактного класса BaseModel.
  2. Каждый из этих подклассов объявляет собственный набор частных строковых полей.
  3. Внутри конструктора подкласса я хочу установить частные поля с карты с использованием Java Reflection. Примером этой функции:

    void setPrivateFields(Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException { 
        for (Map.Entry<String, String> entry : fieldsValuesMap.entrySet()) { 
         String fieldName = entry.getKey(); 
         String fieldValue = entry.getValue(); 
    
         Field field = this.getClass().getDeclaredField(fieldName); 
         field.set(this, fieldValue); 
        } 
    } 
    
  4. Можно ли извлечь из функции я описал в 3), что я не придется переписать алгоритм во всех конструкторах подклассов?

    class BaseModel {} 
    
    class Project extends BaseModel { 
        private String name; 
        private String type; 
    
        public Project(Map<String, String> fieldsValuesMap) { 
         setPrivateFields(fieldsValuesMap); 
        } 
    } 
    
    class Task extends BaseModel { 
        private String description; 
        private String rawDescription; 
    
        public Task(Map<String, String> fieldsValuesMap) { 
         setPrivateFields(fieldsValuesMap); 
        } 
    } 
    
    class SubTask extends BaseModel { 
        ... 
    } 
    
    ... 
    
+0

@jaggedSpire: Из-за сходства между языками, я не уверен, что это проблема встречается только в Java, и вполне вероятно, что решение может лежать меньше в Java, и больше в логике ... Возможно, я ошибаюсь. – abstractx1

+0

Возможный дубликат: http://stackoverflow.com/questions/16428817/convert-a-mapstring-string-to-a-pojo –

+0

@RC: Спасибо, однако, я хочу использовать встроенный Java API. Я обновил свой вопрос. – abstractx1

ответ

2

Вы можете просто добавить его в суперкласса.

class BaseModel { 

    protected void setPrivateFields(Map<String, String> fieldsValuesMap) { 
     for (Map.Entry<String, String> entry : fieldsValuesMap.entrySet()) { 
      String fieldName = entry.getKey(); 
      String fieldValue = entry.getValue(); 

      try { 
       Field field = this.getClass().getDeclaredField(fieldName); 
       boolean access = field.isAccessible(); 
       field.setAccessible(true); 
       field.set(this, fieldValue); 
       field.setAccessible(access); 
      } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
       e.printStackTrace(); 
      }   
     } 
    } 

} 
+0

Это решает проблему, которую я описал, и принимаю ее как есть. Прошу прощения, я не утверждал, что искал решение, которое не влияет на доступность поля. Это также единственное решение, которое я нашел для вас независимо от этой проблемы. Большое вам спасибо за ваше решение и за ваше время. – abstractx1

0

BaseModel.java

abstract class BaseModel { 

} 

Project.java

import java.util.Map; 

class Project extends BaseModel { 
    private String name; 
    private String type; 

    public Project(Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException { 
     Utils.setPrivateFields(this, fieldsValuesMap); 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 
} 

Task.java

import java.util.Map; 

class Task extends BaseModel { 
    private String description; 
    private String rawDescription; 

    public Task(Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException { 
     Utils.setPrivateFields(this, fieldsValuesMap); 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public String getRawDescription() { 
     return rawDescription; 
    } 

    public void setRawDescription(String rawDescription) { 
     this.rawDescription = rawDescription; 
    } 
} 

Utils.java

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

public class Utils { 
    static void setPrivateFields(BaseModel baseModel, Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException { 
     for (Map.Entry<String, String> entry : fieldsValuesMap.entrySet()) { 
      String fieldName = entry.getKey(); 
      String fieldValue = entry.getValue(); 

      Field field = baseModel.getClass().getDeclaredField(fieldName); 
      field.setAccessible(true); 
      field.set(baseModel, fieldValue); 
     } 
    } 
} 

Main.java

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

public class Main { 

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { 
     Map<String, String> map = new HashMap<>(); 
     map.put("name", "ABC"); 
     map.put("type", "XYZ"); 
     Project project = new Project(map); 
     System.out.println(project.getName()); 
     System.out.println(project.getType()); 
    } 
}