【问题标题】:How can I get data of different types from an anonymous class如何从匿名类中获取不同类型的数据
【发布时间】:2023-03-29 05:15:01
【问题描述】:

我有一个对象将一些工作委托给另一个正在实现接口的对象。然后,我正在创建实现此接口的匿名类,我想从中获取信息。

是否可以使用大小为 1 的最终数组作为指向基元的指针来与匿名类共享数据?

这是我的意思的一个工作示例:

public class ExampleClass
{
    public static final int INVALID_VALUE = -1;

    public static void main(final String[] args)
    {       
        final int[] buffer = { INVALID_VALUE }; // buffer is created
        final InterfaceA iaObject = new InterfaceA()
        {
            @Override
            public void doStuff(final String paramA)
            {
                buffer[0] = paramA.length(); // buffer is filled in anonymous class
            }
        };

        final ClassA objA = new ClassA(iaObject);
        objA.doStuff("hello, world");

        if (buffer[0] == INVALID_VALUE) // buffer is used
        {
            System.err.println("Invalid length !");
        }
        else
        {
            System.err.println("The length is : " + Integer.toString(buffer[0]));
        }
    }

    public static class ClassA
    {
        private final InterfaceA iaObject;

        public ClassA(final InterfaceA iaObject)
        {
            this.iaObject = iaObject;
        }

        public void doStuff(final String paramA)
        {
            this.iaObject.doStuff(paramA);
        }
    }

    public static interface InterfaceA
    {
        void doStuff(String paramA);
    }
}

谢谢

【问题讨论】:

  • 为什么不让 doStuff 返回一个 int 呢?
  • 您应该使用 int 而不是数组,因为您只使用一个位置
  • @Zim-ZamO'Pootertoot doStuff 不返回整数,因为我有时需要布尔值、字符串和其他类型的值。
  • @DanielPereira 我必须使用数组,因为我无法在匿名类中引用非最终变量。
  • 所以你想要一个可以做任何事情的函数,并且在运行中更新一些全局变量?这闻起来像是糟糕的代码设计。

标签: java arrays oop coding-style buffer


【解决方案1】:

建议:为什么不对 out 参数使用泛型?

interface InterfaceA {

   public <T> void doStuff( String paramA, Holder<T> holder );
}

class Holder<T> {

    public T t;
}

完整示例:

public class ExampleClass
{
   public static final int INVALID_VALUE = -1;

   public static void main(final String[] args)
   {       
      final InterfaceA< Integer > iaObject = new InterfaceA< Integer >() {
         @Override
         public Integer doStuff( String paramA, Holder<Integer> holder ) {
            return holder.value = paramA.length();
         }
      };

      final ClassA<Integer> objA = new ClassA<>( iaObject );
      int result = objA.doStuff("hello, world", new Holder<>( INVALID_VALUE ));
      if( result == INVALID_VALUE ) {
         System.err.println("Invalid length !");
      }
      else {
         System.err.println("The length is : " + Integer.toString( result ));
      }
   }

   public static class ClassA<T> {
      private final InterfaceA<T> iaObject;

      public ClassA( final InterfaceA<T> iaObject_ ) {
         this.iaObject = iaObject_;
      }

      public T doStuff( final String paramA, Holder<T> holder ) {
         return this.iaObject.doStuff( paramA, holder );
      }
   }

   public static interface InterfaceA<T> {
      public T doStuff( String paramA, Holder<T> resultHolder );
   }

   public static class Holder<T> {

      public T value;

      public Holder( T value_ ) {
         value = value_;
      }
   }
}

【讨论】:

  • 我已经将接口变成了一个抽象的泛型类,其中包含一个 getter 和一个值的 setter。
  • 感谢完整示例,但我无法修改 ClassA 的结构。
【解决方案2】:

如果我理解您的问题的要点,您想知道使用最终数组作为包装器在匿名内部类与其封闭类之间共享内存是否是一种好的设计原则。

根据我的经验,这是在两个对象之间共享数据的一种非常糟糕的方式。以不同的方式声明接口可能更明智。返回一个对象或使用泛型来指定您期望从匿名类返回的类型。

【讨论】:

    【解决方案3】:

    我认为你的方法最大的问题之一是缺乏封装——你的 InterfaceA 实现使用了一些“全局”数据持有者(数组),并且没有办法阻止这个数组可以在其他地方使用,这反过来可能会导致各种问题(竞争条件或其他)。

    更简洁的方法是使用 getInt() 方法或类似方法定义一些单独的类(或接口)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-26
      • 2010-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多