2

多くの計算を含む関数がいくつかあります。すべての計算は、演算子 []、*、/、+、および - を使用して行われます。他に目立っているのは、ループとテストです。したがって、これらの同じ関数は、それらの演算子を実装する任意の型で「使用できます」。double、float、int、long など。パフォーマンス上の理由から、基本型のみを使用します。このジェネリックを行う方法はありますか?

また、パフォーマンス上の理由から、float と int を double にキャストし、double で calc をキャストしたくありません。int では int、float では float、double では double で計算したい。使用する型が異なるだけで同じコードを 3 回書きたくないだけです。

たとえば、あなたが持っていると思います

public double doSomething(double a, double b)
{
    return a * b + 1;
}

もちろん、実際の fn はこれよりもはるかに多くのことを行います。

トリックは次のようなものになると思います

public T doSomething(T a, T b)
{
    return staticAdd(staticMul(a,b),1);
}

…そして、使用されるすべての型に対して基本操作を static fn として定義します。しかし、これらはインライン化されていないため、別の fn 呼び出しが追加されます。

Javaで…のようなことをする方法はあり <T implements +, implements ->ますか?

4

4 に答える 4

2

のようなメソッドを定義するための提案はstaticAdd、最初に考えるほど悪くはありません。HotSpot が (気になったときに) 行うことの 1 つはインライン コードです。関心のある型に対してそのような関数を定義すると、まともなパフォーマンスが得られる可能性があります。

とはいえ、プリミティブでメソッドをジェネリック化できないため、引き続きオートボクシングを扱うことになります。パフォーマンスが本当に重要な場合は、複数のメソッド シグネチャを作成するのに行き詰まっている可能性があります。ただし、 Java/JVM の将来のバージョンでプリミティブが完全になくなる可能性があるという噂があることを考慮してください。もちろん、ラップされた型を扱うことによるペナルティはゼロではありませんが、多くのアプリケーションでは無視できるレベルに近づいています。

于 2013-03-27T02:22:21.977 に答える
1

Java がサポートするオーバーロード演算子は+as stringify と concatenate だけです。これが必要な場合は、Java 以外の JVM 言語のいずれかが必要です。

しかし、古いジョークを思い出してください。

于 2013-03-27T02:16:34.577 に答える
1

簡単に言えば、それは不可能です。Java は静的に型付けされているため、基になる型から操作を抽象化することはできません。

たとえば、基になる型 (Short、Integer など) を抽象化するために、Number に算術演算を定義することはできません。

于 2013-03-27T02:18:55.877 に答える
1

短い答えいいえ、これを行う方法はありません。型システムは、Java でこの種のことを表現するには十分に強力ではありません。

また、ジェネリックではプリミティブ データ型がサポートされていないためIntegersFloatなどのラッパー クラスを使用する必要がある場合があります。

public class Calculator<T extends Number> {
    T add(T a, T b) {
        if (a instanceof Double) {
            return (T) Double.valueOf((a.doubleValue() + b.doubleValue()));
        } else if (a instanceof Float) {
            return (T) Float.valueOf(((a.floatValue() + b.floatValue())));
        } else if (a instanceof Integer) {
            return (T) Integer.valueOf(((a.intValue() + b.intValue())));
        }
        throw new IllegalArgumentException();
    }
}

以下と同じように呼び出すことができます。

Calculator<Double> c1 = new Calculator<Double>();
mc.add(1.0, 1.1);

Calculator<Integer> c1 = new Calculator<Integer>();
mc.add(1, 2);
于 2013-03-27T02:35:03.360 に答える