2008-11-09 24 views
11

tôi đang tìm cách để thực hiện một cái gì đó trong Java dọc theo dòng:Thiết biến bằng tên trong 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(){} 
} 

... nơi một biến được thiết lập dựa trên tên biến mà không có tên biến mã hóa cứng và không sử dụng bất kỳ cấu trúc dữ liệu nào khác. Điều này có thể không?

Trả lời

24

Đây là cách bạn có thể thực hiện setAttribute sử dụng phản chiếu (Tôi đã đổi tên chức năng; có chức năng phản chiếu khác nhau với nhiều loại lĩnh vực khác nhau):

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

Nói chung, bạn muốn sử dụng Phản chiếu. Dưới đây là phần giới thiệu tốt về các trường hợp topic with examples

Cụ thể, phần "Thay đổi giá trị của trường" mô tả cách thực hiện những gì bạn muốn làm.

Tôi lưu ý rằng tác giả cho biết, "Tính năng này cực kỳ mạnh và không tương đương với các ngôn ngữ thông thường khác". Tất nhiên, trong mười năm qua (bài viết được viết vào năm 1998), chúng tôi đã thấy những bước tiến lớn được thực hiện bằng ngôn ngữ năng động. Ở trên là khá dễ dàng thực hiện trong Perl, Python, PHP, Ruby, và như vậy. Tôi nghi ngờ đây là hướng bạn có thể đến từ dựa trên thẻ "eval".

+0

liên kết dường như bị phá vỡ; ( – Vlad

+0

Tôi đã khắc phục liên kết –

+0

liên kết bị phá vỡ một lần nữa – SimonPip

3

Ngoài ra, hãy xem BeanUtils có thể ẩn một số sự phức tạp của việc sử dụng phản chiếu từ bạn.

0

Bạn có thể muốn bộ nhớ cache một số dữ liệu phản ánh trong khi bạn đang ở đó:

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

Tại sao bận tâm khi lớp phản chiếu rồi.. đọc bộ mã nguồn cho java.lang.Class và xem cho chính mình, nó thậm chí xử lý việc làm mất hiệu lực bộ đệm ẩn khi một lớp được nạp lại. –

1

Tùy thuộc vào cách sử dụng, bạn có thể sử dụng phản ánh như khuyên ở trên, hoặc có lẽ một HashMap sẽ phù hợp hơn ...

1

Câu hỏi này dành riêng cho int, điều này rất hữu ích, tuy nhiên đây là một cái gì đó chung chung hơn một chút. Kiểu phương thức này hữu ích nếu bạn đang tải trong các biểu tượng String của cặp giá trị tên trường/trường.

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

} 
Các vấn đề liên quan