Является ли Java слабой типизацией, как показано в этом примере по сравнению с python?

Я знаю, что такое сильные и слабые типы. Я также знаю, что Java строго типизирована. теперь я изучаю python, и это язык со строгой типизацией. Но теперь я вижу, что Python «более» строго типизирован, чем Java. пример для иллюстрации

public class StringConcat {

  public static void main(String[] args) {
      String s="hello ";
      s+=4;
    System.out.println(s);
}
}

Нет ошибок и печатает привет 4

в питоне

>>> x="hello"
>>> x+=4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

так что этот пример демонстрирует, что python строго типизирован. если только Java под капотом не выполняет некоторые манипуляции для преобразования int в String и выполнения String concat.


person eagertoLearn    schedule 30.08.2013    source источник
comment
если только Java под капотом не выполняет некоторые манипуляции для преобразования int в String и выполнения конкатирования строк. Да, это происходит.   -  person Sotirios Delimanolis    schedule 30.08.2013
comment
Конкатенация строк — особый случай в Java. В JLS есть язык, в котором говорится, что для оператора + происходит автоматическое преобразование (с использованием toString) (и это относится к +=, как указал Прашант), но нет другого подобного случая, когда происходит такое преобразование между несвязанными типами. Я бы не назвал Java слабо типизированной из-за этого единственного исключения из правил.   -  person ajb    schedule 30.08.2013


Ответы (3)


Java по-прежнему строго типизирована, несмотря на ваш пример. Код эквивалентен

String s = "hello ";
s = s + 4;

и Java преобразует 4 в строку, а затем выполняет конкатенацию строк. Это особенность языка.

Однако в Python вы не можете использовать + для присоединения 4 к вашей строке, потому что язык не позволяет преобразовать ее в str. Как вы заметили, Java делает это за вас под капотом.

person Prashant Kumar    schedule 30.08.2013

Этот пример не доказывает, что Java не строго типизирована. Есть только неявный преобразование строк (JLS, раздел 5.1.11) происходит за кулисами.

Сначала происходит преобразование в ссылочный тип для создания Integer из литерала int (new Integer(4)), затем вызывается toString() для преобразования его в String для конкатенации.

person rgettman    schedule 30.08.2013
comment
Я не думаю, что для этого нужен бокс. Меня не было до автобокса, но я думаю, что тогда код все еще работал. Кроме того, StringBuilder имеет append перегрузки для примитивы. - person user2357112 supports Monica; 30.08.2013
comment
@user2357112 user2357112 В предоставленной мной ссылке JLS не упоминается бокс, она просто преобразована в эталонное значение. Я изменил эту часть своего ответа. - person rgettman; 30.08.2013
comment
@ user2357112: Определение JLS заключается в том, что когда + используется для строки и чего-то еще, метод toString() вызывается для другого операнда, а примитивы, такие как int, не имеют toString() или каких-либо других методов. Так что это должно быть упаковано (или как вы хотите это назвать) в Объект. Может быть, у JLS был какой-то специальный язык для обработки этого случая до автоупаковки - я не знаю. - person ajb; 30.08.2013
comment
Похоже, что в JLS упоминается, что реализации могут оптимизировать ненужные преобразования, но он определяет результаты с точки зрения эквивалентной, менее эффективной реализации. Фактические JVM не будут создавать промежуточные объекты Integer или String. - person user2357112 supports Monica; 30.08.2013

Если вам нужен еще один забавный пример, вы можете найти во многих местах уродливые

intNumber+""

для преобразования числа в строку. Программисты ленивы и не хотят писать

Целое.toString(intNumber)

И это вызывает преобразование строк И бесполезную конкатенацию строк во время выполнения.

Это не означает, что Java не является строго типизированной, просто все объекты должны иметь метод toString(), и все примитивы могут автоматически упаковываться и распаковываться в их непримитивные аналоги (int -> Integer, long -> Long и т. д.). ), которые реализуют toString(), а "+" в java действует как конкатенация строк.

person Simone Gianni    schedule 30.08.2013