Java Generic: оператор - не определен для типа (ов) аргумента T, T [duplicate]

Строка ошибки «Ссылка на объект, не установленная на экземпляр объекта.» указывает, что вы не назначили экземпляр объекта объектной ссылке, и все же вы получаете доступ к свойствам / методам этого объекта.

например: скажем, у вас есть класс под названием myClass и он содержит одно свойство prop1.

public Class myClass
{
   public int prop1 {get;set;}
}

Теперь вы получаете доступ к этому prop1 в каком-то другом классе, как показано ниже:

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref.prop1 = 1;  //This line throws error
     }
}

выше строки выдает ошибку, потому что ссылка класса myClass объявлена, но не создана, или экземпляр объекта не назначается referecne этого класса.

Чтобы исправить это, вам нужно создать экземпляр (присвоить объект ссылке на этот класс).

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref = new myClass();
        ref.prop1 = 1;  
     }
}
32
задан MPelletier 8 December 2011 в 12:34
поделиться

9 ответов

Вы говорите, что не знаете, являются ли ваши числа целыми или плавают ... когда вы используете класс Number, компилятор также не знает, являются ли ваши числа целыми числами, плавающими или другими. В результате основные математические операторы, такие как + и - не работают; компьютер не знал, как обрабатывать значения.

START EDIT

Основываясь на обсуждении, я подумал, что пример может помочь. Компьютеры хранят числа с плавающей запятой как две части, коэффициент и показатель. Таким образом, в теоретической системе 001110 может быть разбит как 0011 10 или 32 = 9. Но положительные целые числа сохраняют числа как двоичные, поэтому 001110 также может означать 2 + 4 + 8 = 14. Когда вы используете класс Number , вы сообщаете компьютеру, которого не знаете, является ли число float или int или что, поэтому он знает, что он имеет 001110, но он не знает, означает ли это 9 или 14 или какое-то другое значение.

END EDIT

Что вы можете сделать, так это сделать небольшое предположение и преобразовать в один из типов для математики. Таким образом, у вас может быть

Number c = a.intValue() + b.intValue();

, который вы также можете превратить в

Integer c = a.intValue() + b.intValue();

, если вы готовы перенести некоторую ошибку округления или

Float c = a.floatValue() + b.floatValue();

, если вы подозреваете, что не имеете дело с целыми числами, и все в порядке с возможными незначительными проблемами точности. Или, если вы предпочтете вместо этого ошибку небольшой удар,

BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue()));
19
ответ дан Pops 25 August 2018 в 02:30
поделиться

Лучшим ответом будет сделать использование с двойной диспетчерской бурение до самых известных типов (посмотрите на реализацию addtition Smalltalk)

0
ответ дан azis.mrazish 25 August 2018 в 02:30
поделиться

Используйте следующее:

Number c = a.intValue() + b.intValue(); // Number is an object and not a primitive data type.

Или:

int a = 2;
int b = 3;
int c = 2 + 3;
3
ответ дан Elie 25 August 2018 в 02:30
поделиться

Я думаю, что на ваш вопрос есть две стороны.

Почему оператор + не поддерживается на Number?

Поскольку спецификация языка Java. не указывает это, и нет перегрузки оператора. Существует также не естественный способ компиляции, чтобы отнести число к некоторому фундаментальному типу, и нет никакого естественного добавления для определения для какого-либо типа операций.

Почему основные арифметические операции не поддерживаются on Number?

(Скопировано из моего комментария:)

Не все подклассы могут реализовать это так, как вы ожидали. Особенно с типами Atomic трудно определить полезный контракт, например. Добавить.

Кроме того, добавление метода будет проблемой, если вы попытаетесь добавить Long to Short.

2
ответ дан extraneon 25 August 2018 в 02:30
поделиться

Number - класс abstract, который вы не можете создать. Если у вас есть правильный экземпляр, вы можете получить number.longValue() или number.intValue() и добавить их.

0
ответ дан fastcodejava 25 August 2018 в 02:30
поделиться

Единственный способ правильно добавить любые два типа java.lang.Number:

Number a = 2f; // Foat
Number b = 3d; // Double
Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) );

Это работает даже для двух аргументов с другим типом номера. Он будет (должен?) Не производить никаких побочных эффектов, таких как переполнение или потеря точности, поскольку toString () числового типа не снижает точность.

8
ответ дан Fritz Mock 25 August 2018 в 02:30
поделиться

java.lang.Number является просто суперклассом всех классов-оболочек примитивных типов (см. java doc ). Используйте подходящий примитивный тип (double, int и т. Д.) Для вашей цели или соответствующий класс оболочки (Double, Integer и т. Д.).

Рассмотрим следующее:

Number a = 1.5; // Actually Java creates a double and boxes it into a Double object
Number b = 1; // Same here for int -> Integer boxed

// What should the result be? If Number would do implicit casts,
// it would behave different from what Java usually does.
Number c = a + b; 

// Now that works, and you know at first glance what that code does.
// Nice explicit casts like you usually use in Java.
// The result is of course again a double that is boxed into a Double object
Number d = a.doubleValue() + (double)b.intValue();
7
ответ дан mc10 25 August 2018 в 02:30
поделиться

Было бы также работать над тем, чтобы обработать добавление для вас. Теперь я не знаю, как это повлияет на производительность, но я предполагаю, что это будет меньше, чем использование BigDecimal.

public static Number addNumbers(Number a, Number b) {
    if(a instanceof Double || b instanceof Double) {
        return new Double(a.doubleValue() + b.doubleValue());
    } else if(a instanceof Float || b instanceof Float) {
        return new Float(a.floatValue() + b.floatValue());
    } else if(a instanceof Long || b instanceof Long) {
        return new Long(a.longValue() + b.longValue());
    } else {
        return new Integer(a.intValue() + b.intValue());
    }
}
9
ответ дан SkidRunner 25 August 2018 в 02:30
поделиться

Прежде всего, вы должны знать, что Number является абстрактным классом. Что происходит здесь, так это то, что когда вы создаете свои 2 и 3, они интерпретируются как примитивы, и в этом случае создается подтип (я думаю, Integer). Поскольку Integer является подтипом Number, вы можете назначить вновь созданное Integer в ссылку Number.

Однако число - это просто абстракция. Он может быть целым числом, он может быть плавающей точкой и т. Д., Поэтому семантика математических операций будет неоднозначной.

Число не предоставляет классические операции карты по двум причинам:

Во-первых, методы-члены в Java не могут быть операторами. Это не C ++. В лучшем случае они могли бы предоставить add ()

Во-вторых, выясняя, какой тип операции делать, когда у вас есть два входа (например, разделение поплавка на int), довольно сложно.

. Вместо этого вы несете ответственность за преобразование обратно к определенному примитивному типу, который вам интересен, и примените математические операторы.

0
ответ дан Uri 25 August 2018 в 02:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: