Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字段子类访问-可能的最佳方式_Java_Reflection_Annotations_Field_Getter - Fatal编程技术网

Java 字段子类访问-可能的最佳方式

Java 字段子类访问-可能的最佳方式,java,reflection,annotations,field,getter,Java,Reflection,Annotations,Field,Getter,因此,我在处理程序中的首选项时遇到了一些问题。考虑到将使用的次数,最好使用单一方法。每个变量的getter可能会导致一个更大的文件 (5个字段*200到300个类=大量浪费的空间) 我试图找出如何从子类访问具有已定义和常量名称的字段。 超类是抽象的,在列表中定义,我可以完全访问它。这是我想让这个领域的获得者参加的课程 我希望它的工作方式是这样的: import java.lang.reflect.Field; public class Test { public Test() {

因此,我在处理程序中的首选项时遇到了一些问题。考虑到将使用的次数,最好使用单一方法。每个变量的getter可能会导致一个更大的文件

(5个字段*200到300个类=大量浪费的空间)

我试图找出如何从子类访问具有已定义和常量名称的字段。

超类是抽象的,在列表中定义,我可以完全访问它。这是我想让这个领域的获得者参加的课程

我希望它的工作方式是这样的:

import java.lang.reflect.Field;

public class Test {

    public Test() {
        final B b = new B();
        final C c = new C();
        System.out.println(b.getFoo());
        System.out.println(c.getFoo());
    }

    public static void main(String[] args) {
        new Test();
    }

    public class A {

        public String getFoo() {
            try {
                Field f = this.getClass().getField("FOO");
                f.setAccessible(true);
                return (String) f.get(null);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

    }

    public class B extends A {

        private static final String FOO = "$HOME.DIR/lib/res/image1.png";

    }

    public class C extends A {

        private static final String FOO = "$HOME.DIR/lib/res/image2.png";

    }

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

public class Test 
{
    public Test() 
    {
        final B b = new B();
        final C c = new C();
        System.out.println(b.getFoo());
        System.out.println(c.getFoo());
    }

    public static void main(String[] args)
    {
        new Test();
    }
}

class A 
{
    private static final Map<String, String> values;

    static
    {
        values = new HashMap<String, String>();
    }

    public String getFoo() 
    {
        return (values.get("FOO"));
    }

    protected static void addValue(final String key,
                                  final String value)
    {
        values.put(key, value);
    }
}

class B extends A 
{
    static
    {
        addValue("FOO", "$HOME.DIR/lib/res/image1.png");
    }
}

class C extends A 
{
    static
    {
        addValue("FOO", "$HOME.DIR/lib/res/image2.png");
    }
}
想必,这是行不通的。类
A
不包含字段“FOO”。理想情况下,如果它成功了,我会希望它打印出来:

$HOME.DIR/lib/res/image1.png
$HOME.DIR/lib/res/image2.png

我(到目前为止)认为这是可能的:

  • 倒影
  • 使用Getter-希望避免
  • 使用注释
  • 使用注释是我认为可能的一种方式,但我通常不喜欢注释的整体概念,但如果这是唯一的方式,我当然会接受它


    感谢您阅读本文,希望您能提供一些见解。

    您能否更详细地描述您的更高级别问题,因为听起来您可能需要进行一些设计更改来缓解此问题。通过反射访问父类中的子类字段通常看起来是个坏主意

    但是,如上所述,为了通过反射访问私有字段,需要使用
    getDeclaredField
    而不是
    getField

    例如


    你可以用一张地图,像这样:

    import java.lang.reflect.Field;
    
    public class Test {
    
        public Test() {
            final B b = new B();
            final C c = new C();
            System.out.println(b.getFoo());
            System.out.println(c.getFoo());
        }
    
        public static void main(String[] args) {
            new Test();
        }
    
        public class A {
    
            public String getFoo() {
                try {
                    Field f = this.getClass().getField("FOO");
                    f.setAccessible(true);
                    return (String) f.get(null);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
    
        }
    
        public class B extends A {
    
            private static final String FOO = "$HOME.DIR/lib/res/image1.png";
    
        }
    
        public class C extends A {
    
            private static final String FOO = "$HOME.DIR/lib/res/image2.png";
    
        }
    
    }
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class Test 
    {
        public Test() 
        {
            final B b = new B();
            final C c = new C();
            System.out.println(b.getFoo());
            System.out.println(c.getFoo());
        }
    
        public static void main(String[] args)
        {
            new Test();
        }
    }
    
    class A 
    {
        private static final Map<String, String> values;
    
        static
        {
            values = new HashMap<String, String>();
        }
    
        public String getFoo() 
        {
            return (values.get("FOO"));
        }
    
        protected static void addValue(final String key,
                                      final String value)
        {
            values.put(key, value);
        }
    }
    
    class B extends A 
    {
        static
        {
            addValue("FOO", "$HOME.DIR/lib/res/image1.png");
        }
    }
    
    class C extends A 
    {
        static
        {
            addValue("FOO", "$HOME.DIR/lib/res/image2.png");
        }
    }
    
    import java.util.HashMap;
    导入java.util.Map;
    公开课考试
    {
    公开考试()
    {
    最终B=新B();
    最终C=新C();
    System.out.println(b.getFoo());
    System.out.println(c.getFoo());
    }
    公共静态void main(字符串[]args)
    {
    新测试();
    }
    }
    甲级
    {
    私有静态最终映射值;
    静止的
    {
    values=newhashmap();
    }
    公共字符串getFoo()
    {
    返回(value.get(“FOO”);
    }
    受保护的静态void addValue(最终字符串键,
    最终字符串值)
    {
    value.put(键、值);
    }
    }
    B类扩展了A类
    {
    静止的
    {
    addValue(“FOO”,“$HOME.DIR/lib/res/image1.png”);
    }
    }
    C类扩展了
    {
    静止的
    {
    addValue(“FOO”,“$HOME.DIR/lib/res/image2.png”);
    }
    }
    
    我想知道为什么在您的脑海中更容易放置
    私有静态最终字符串FOO=“$HOME.DIR/lib/res/image2.png”在子类中,而不是将
    公共字符串getFOO(){return“$HOME.DIR/lib/res/image2.png”}
    放在子类中,两者的字符长度大致相同,并且都可以在所有200-300个子类中通过剪切/粘贴/键入来完成。(您可以使用一个属性文件,其中所有字符串都按类名索引,如
    B=$HOME.DIR/lib/res/image2.png
    和a中的getFoo()方法)。这既可以学习,也可以扩展(希望打开API),还可以真正消除混乱。我真的只是为了演示而在前面放了
    private static final
    ,但根本不需要这些。它只会有一个实例,所以不需要只维护一个这样的变量。遗憾的是,即使从静态更改为使用getDeclaredField,它也失败了。正如我在上面的课程中指出的,数据类型的最终修订版可以归结为:
    stringfoo=“this”上面的代码将与静态代码一起使用。如果使用非静态,则需要将实例传递给f.get,而不是null。@图例,我将上面的代码更改为只包含getDeclaredField,效果很好…@图例,上面的代码不需要此功能,但如果要访问非静态内容,则需要指定要使用的实例,这是你的案子要考虑的问题。这真的应该被当作最后的手段。可能在编辑现有类时是绝对不可能的。反射功能强大,但速度非常慢,应该谨慎使用。另一个问题是它不是重构安全的,即如果您将FOO的名称更改为其他名称,您的IDE将不会修改类A中的代码。如果你只是在试验,那就继续。。。