【问题标题】:Is there a way to achieve implicit type cast or conversion in java有没有办法在java中实现隐式类型转换或转换
【发布时间】:2013-08-22 16:25:03
【问题描述】:

我想创建一个采用enum 并直接在计算中使用它的方法

  private static int getEntries(List<Integer> vector, Sign sign)
  {
    //assert isPrimitiveTypeCompliant(vector) : "Vector has null components!";
    int entries = 0;

    for (Integer entry : vector)
      if (entry * sign > 0) // does not compile
        entries++;

    return entries;
  }

我想……这样是可能的,因为我假设 System.out.println(Object) 也进行隐式类型转换。它没有,它使用以下方法:

 public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }

 public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
    }

问题

那么有可能在java中实现吗?还是保留给C++ 和运算符重载?常见的解决方法是什么?完成工作的实用程序/适配器类?


顺便说一句,我最终采用了这种方法

  private enum Sign
  {
    POSITIVE(+1), NEGATIVE(-1);

    private int sign;

    private Sign(int sign)
    {
      this.sign = sign;
    }

    public int process(int n)
    {
      if (n * sign > 0)
      {
        return n;
      }
      return 0;
    }
  }

  private static int getEntries(List<Integer> vector, Sign sign)
  {
    //assert isPrimitiveTypeCompliant(vector) : "Vector has null components";
    int entries = 0;

    for (Integer entry : vector)
      entries += sign.process(entry);

    return entries;
  }

【问题讨论】:

  • sign.ordinal() 是一个选项。
  • 我认为 Josh Bloch 写道,普通开发人员不应该依赖 ordinal() 函数。但具体原因我忘了。
  • 枚举基本上是一个集合,而不是一个列表。集合本质上不是有序的,其他开发人员倾向于对它们重新排序。事实上,他们做到了!!!
  • 原因是如果你使用序数,那么当你扩展枚举时,你只能在末尾添加值,不能在中间或其他地方,否则你会破坏所有依赖于序数的东西.这是在工作中来之不易的经验,有一段时间我们将序数存储在数据库表等中。这使得代码的灵活性远远低于应有的灵活性。我们现在已经承诺不对新代码使用序数。
  • @MarioRossi 你打赌。在我刚开始在公司时,序数被广泛使用,我不得不四处向许多人解释为什么这是一个糟糕的想法。它不仅禁止在除末尾之外的任何地方添加值,而且当您有多个必须合并的分支(将新值添加到同一个枚举)时,至少其中一个可以保证打破“添加在末尾" 规则。

标签: java casting type-conversion implicit-conversion


【解决方案1】:

为什么不直接使用 sign 的 int 值

if (entry * sign.value > 0)



enum Sign

    public final int value;

【讨论】:

  • 最好引入显式属性。从概念上讲(或至少对于大多数开发人员而言),枚举常量不应依赖于声明顺序。他们将重新订购!!!
【解决方案2】:

是的,有可能实现它。事实上,你在第二段代码中就做到了。

Java 没有运算符重载或隐式转换(除了数值转换和“扩大”类型转换)。所以,没有办法允许像entry * sign 这样的语法(除了你使用的那个)。

什么是解决方法?这不是问题。这是一个语言设计决策。而且您已经成功地掌握了适当的 Java 习语。

【讨论】:

  • 是的,Integer 到int 的拆箱。好的,明确的答案。想也许还有更多。
  • 你遇到过实现闭包/lambda表达式的惯用语吗?这没什么!太糟糕了,很快就会有更好的支持。我认为枚举/运算符重载/隐式转换永远不会是这种情况,因为习语相对简单或/并且所需更改的影响太深。
  • 函数式编程是正确的标语。我在示例中需要的只是一个简单的map 函数。 ...您的意思是Java 8中的那些不好?它们仍然很冗长,但我还没有仔细观察。
  • 但是我们不要对 Java 不公平。对于一门有近 20 年历史的语言、它执行的上下文(从服务器到智能卡)以及我们所看到的范式转变,Java 破坏的代码行数极少。这一直是一个关键的语言设计标准,我相信公司会欣赏它。
  • 也许“范式转变”是夸大其词。但是,是的,从 OOP 到 OOP+功能的程序。还有二进制/平面文件到 XML/JSon。基于文本到(传统)图形到 HTML 的用户界面。数据库共享到 DCE/CORBA 到 Web 服务到云服务。瘦客户端到胖客户端再到新型瘦客户端。我可能错过了很多。
【解决方案3】:

我认为对于这种情况,使用 final 静态变量会更好。

public final class Sign {
    public final static int POSITIVE = 1;
    public final static int NEGATIVE = -1;

    private Sign() {
    }
}

然后您可以使用Sign.POSITIVE 和Sign.NEGATIVE 进行您想要的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    相关资源
    最近更新 更多