В соответствии с Спецификацией языка Java :
Если целочисленное умножение переполняется, то результатом являются младшие биты математического произведения, представленные в некоторых достаточно большихдва дополнения формата.В результате, если происходит переполнение, знак результата может не совпадать со знаком математического произведения двух значений операнда.
Вы умножаете на целые числа, которые переполняются, затемсохраните результат в длинном, что не поможет.
Вы должны явно использовать длинные литералы:
long l = 50000L * 50000L;
long l = 50000L * 50000; // this also works
или привести к длинному перед умножением:
long l = ((long) 50000) * ((long)50000);
long l = ((long) 50000) * 50000; // this also works
См. spec , чтобы понять, почему достаточно явно использовать только один длинный литерал или один приведение к long.