有些人可以说像Java或Groovy这样的语言被认为是静态或动态类型还是动态语言?

时间:2013-01-24 20:31:46

标签: java groovy

我只是试图了解何时是一种已知静态或动态类型的编程语言或同时被视为静态类型和动态语言或动态类型和动态语言的概念。

我感到困惑的是,如果在Java的情况下,在编译时知道或定义变量的类型时,已知某种语言是静态类型的,那么

//Java illustration of statically typed  
int x, y; //explicit type declaration 
x = 5, y = 10; //Now we use the variables 

//Groovy illustration of statically typed 
def x, y //explicit type declaration 
x = 1, y = 10 //now we use the variables

基于阅读各种在线资源,它表示被认为是静态类型的语言列表不包括Groovy,而是Java和C ++。

此外,如果Groovy是一种动态语言(DL-DL的定义是一种在编译时很少或不执行检查的语言,而是在运行时进行检查)。这是否意味着Groovy也是一种动态类型语言,因为对于一个被认为是动态类型的变量“就是在运行时知道变量的类型而不是编译时”。

//Illustration of a language being dynamically typed according to DT and DL definition
x = 5 //directly using the variable (exceptable in Python and PHP but not in Java/Groovy)

如果在Groovy中就是这种情况,那么Groovy静态类型的代码说明与Groovy在运行时完成的检查定义相矛盾。

这是否意味着两个java groovy都不是动态类型语言,因为直接使用变量会在Java和groovy中抛出编译器错误。

如果错了,请纠正我。请提供示例代码示例。

3 个答案:

答案 0 :(得分:1)

静态和动态类型主要描述如何键入变量(以及函数参数和返回值)。在许多静态类型语言中,您必须声明变量的类型,以便编译器知道哪些操作有效以及应该使用哪些过载版本的函数/运算符。一些现代静态类型语言(包括大多数函数式语言)具有类型推断,因此大多数情况下您不必声明变量的类型。但是,变量仍必须具有固定类型。如果将不同类型的值分配给同一个变量,编译器将拒绝编译,或者只允许您执行所有操作。真正强类型的语言不能与类型相关的运行时故障。

在动态类型语言中,变量只是一个名称。您可以将任何类型的值分配给任何变量,并且可以通过分配不同类型的值来更改类型。只能在执行语句时检查函数调用或对变量的操作的有效性。 (您可以将此视为将Java中的每个变量声明为Object并在使用时将它们转换为所需类型。当然,编译器不会尝试确定转换是否成功并且将插入可能导致运行失败的强制转换检查时间。)

动态语言通常意味着放松编译器检查的大多数事物(语法可能是事先检查的唯一事物)。这通常意味着变量存在甚至函数调用有效性在必要时都不会被验证。他们通常使用动态类型,因为静态类型不利于放松。

答案 1 :(得分:1)

我把它作为评论,但它被埋了一点。

def DOES给出一个类型,它使用“对象”的类型。就好像Java中定义的每个变量都被定义为一个对象...(因此,Groovy中的def x = 7与Java中的Object x = 7完全相同,没有更多或更少的类型)。

这些对象始终用两种语言来表达他们的类型信息。这两个也是等效的:

Groovy:
def x=5
assert(x == 5)
x="Hey, I changed type!"
assert(x == "Hey, I changed type!")

Java:
Object x=5
assert(x == 5);
x="Hey, I--well I kinda changed my type!"
assert(x.equals("Hey, I--well I kinda changed my type!"))

最大的区别在于Java强制(在编译时)你只调用它认为你拥有的类类型的已知方法..所以在上面的例子中,.toString()和.equals()实际上是只有有用的方法。要做数学,你必须做这样的事情:

Object x=5;
Object y=7;
Object z=(int)x + (int) y;
assert(z == 12);  
// I believe Integer z will automatically turn 
// to an int here, but this might not compile :)

在Groovy中,语言只会尝试调用该方法,并在运行时成功或失败。

这可以通过使用反射来模拟Java,您可以将所有内容键入“Object”(就像使用groovy的“def”一样)并编写一个反射实用程序来执行以下操作:

Object s="Hey, Wassup???";
Object s2=magic(s, "toLowerCase")
assert(s2.equals("hey, wassup???"));

Groovy只是隐藏了“魔法”。

所以我认为你不能说一个本身就比另一个更具动态性,尽管你可能会说使用反射会使两种语言都变得动态,你也可以说Groovy使用的反射比java更多......

答案 2 :(得分:0)

请注意,在Java中,您必须告诉它变量的完整类型。你的例子中的'int'。你可以说'浮动'或'地图'或'MyClassWithALongName'。

在Groovy中你刚才说'def'表示有一个变量,但你没有告诉它内容类型。