首先Groovy也是运行在java虚拟机上的,二者有语法上的区别但是和java并没有本质上的不同。
Groovy和java是相结合的关系而并不是将java取而代之。
1、Java开发者学习Groovy的成本很低
2、是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言
3、完成同样的事情Groovy可能比Java需要写的代码要少
4、支持单元测试和模拟(对象),可以 简化测试
5、groovy中基本类型也是对象,可以直接调用对象的方法
......
1
2
3
4
5
6
7
8
9
def var="hello "+
"world"+
",groovy!"
def repeat(val){
for(i = 0; i < 5; i++){
println val
}
}
repeat(var)
输出:
hello world,groovy!
hello world,groovy!
hello world,groovy!
hello world,groovy!
hello world,groovy!
最后,为什么要学,这是给那些比较“懒”的java程序员准备的,代码量小啊,而且一些新特性用起来也很方便省心。
㈡ java程序员为什么使用Groovy
正如Groovy对Java很多特性进行的包装优化一样,基于Groovy的HttpBuilder也包裹了HttpClient,使网络编程变得更加的方便易用,下面稍微来用一个例子看一下。
寻找各种依赖的jar包有时候会让我们失去耐心,不过值得庆幸的是我们有Maven和Gradle这样的工具,可以根据配置轻松的帮我们配置好我们需要的数据。下面我们来叙述一下整个过程。
1. 创建文件夹httpbuildertest
2. 创建gradle配置文件,build.gradle,内容如下:
apply plugin: "groovy"
apply plugin: "eclipse"
repositories {
mavenCentral()
}
dependencies {
compile "org.codehaus.groovy:http-builder:0.4.0"
compile "org.codehaus.groovy:groovy-all:2.3.3"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}
gradle我们将做另文介绍
3. 执行gralde eclipse(当然必须先安装gradle),就可以生成eclipse所需要的.classpath和.project文件,这时候就可以使用eclipse导入功能来import->Existing Projects Into WorkSpace。
4. 创建我们的一个测试,试试看是不是可以使用httpbuilder了
import groovyx.net.http.HTTPBuilder
import spock.lang.Specification;
import static groovyx.net.http.Method.*
import static groovyx.net.http.ContentType.*
class HttpbuildLabSpec extends Specification{
HTTPBuilder http = new HTTPBuilder( 'http://m.weather.com.cn' )
public void testRequestWeather(){
when:
def info =""
http.request( GET, JSON ) {
url.path = '/data/101290401.html'
headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
response.success = { resp, json ->
info = json.weatherinfo.city
}
response.failure = { resp -> println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}" }
}
then: "曲靖"==info
}
}
打完收工,通过这个小例子我们可以了解到这么一些内容:
(1)HTTPBuilder 是这个框架的核心类(要不然怎么和框架一个名字),构建这个类的对象的时候,指定要请求的baseUrl。
(2)request方法可以指定请求的method和返回的数据格式,method对应的是GET/PUT/POST/DELETE/HEAD几个常量,而数据格式目前有JSON/XML/HTML/BINARY/URLENC/ANY几种。
(3)一个比较有意思的地方是,在http的request方法里面,仿佛是无根之水一样突然冒出来了几个没有声明过的变量,看起来连编译也不会通过的方法,那么是如何能正常运作的呢?这个我们就要研究到Groovy的Closure(闭包)。Groovy的闭包里包含有一个delegate属性,一般来说,这个delegate里保存的是闭包使用上下文的对象引用,比如a调用了一个闭包b,则b的delegate就是a的this对象。而在HTTPBuilder对象调用request方法的时候,它把传入闭包的delegate改成了一个叫做SendDelegate的类对象(这是HTTPBuilder的内部类,他们都是用Java写的,在新版的HttpBuilder里,已经改名为RequestConfigDelegate),这个类里面,分别包含了一个叫做getHeaders()的方法,一个叫做getUrL()的方法,一个叫做getResponse()的方法。稍微思索一下我们就可以想到,Groovy里有这样的特性,如果直接使用一个识别不出来的变量,Groovy会假设它是getter的一种简写形式,自动进行补全(当然这也是DSL的常用伎俩,把方法伪装成短语),而getter并没有参数,所以其括号是可以简写的,实际上上面的代码可以写作getUrl().path = '/data/101290401.html',这样就非常符合程序员的视觉体验了。
(4)主要是为了喜欢追根问题的同学释疑,实际上整个调用还是非常的简单明快的,在request闭包里,我们通过response(记得吗,实际上就是GetResponse()),获得了一个Map结构,这个Map的内部结构实际上是Map<String,Closure>,对“success”和“failure”这两个key我们分别设置了对应的闭包,这样就完成了回调的设置,一旦方法成功或者失败,就可以调用到对应的闭包。
(5)使用了JSON作为返回格式,闭包的第二个参数就是解析好的返回body,就是一个Json对象,是可以直接用点号来访问的。当然最好不要在失败的闭包里放这个参数,一般失败的情况比较多,也许就是一个html返回,格式错误那么测试也就无法按照预期进行了。
㈢ Assert 在Java和Groovy中的区别 / 蓝讯
与 Java 的区别
Groovy 试图尽可能地让 Java 开发者快速适应。在设计 Groovy 时,我们努力不让用户感到惊讶,即遵循“最小惊讶”原则,特别是针对那些此前有 Java 开发背景的 Groovy 初学者。
下面讲讲 Groovy 与 Java 的主要不同点。
1. 默认导入
下面这些包和类都是默认导入的,也就是说,不用再显式地使用 import 语句了:
java.io.*
java.lang.*
java.math.BigDecimal
java.math.BigInteger
java.net.*
java.util.*
groovy.lang.*
groovy.util.*
2. 多重方法
在 Groovy 中,调用的方法将在运行时被选择。这种机制被称为运行时分派或多重方法(multi-methods),是根据运行时实参(argument)的类型来选择方法。Java 采用的是相反的策略:编译时根据声明的类型来选择方法。
下面的 Java 代码可以用 Java 和 Groovy 来编译,但两种编译结果截然不同:
int method(String arg) {
return 1;
}
int method(Object arg) {
return 2;
}
Object o = "Object";
int result = method(o);
用 Java 编译的结果如下:
assertEquals(2, result);
用 Groovy 编译的结果则为:
assertEquals(1, result);
产生差异的原因在于,Java 使用静态数据类型,o 被声明为 Object 对象,而 Groovy 会在运行时实际调用方法时进行选择。因为调用的是 String 类型的对象,所以自然调用 String 版本的方法。
3. 数组初始化表达式
在 Groovy 中,{...} 语句块是留给闭包(Closure)使用的,这意味着你不能使用以下这种格式来创建数组:
int[] array = { 1, 2, 3}
正确的方式是这样的:
int[] array = [1,2,3]
4. 包范围可见性
在 Groovy 中,如果某个字段缺失了修饰符,并不会导致像在 Java 中那样形成包的私有字段:
class Person {
String name
}
相反,它会用来创建一个属性(property),也就是一个私有字段(private field),以及一个关联的 getter 和一个关联的 setter。
在 Groovy 中创建包私有字段,可以通过标注 @PackageScope 来实现。
class Person {
@PackageScope String name
}
5. ARM 语句块
ARM(Automatic Resource Management,自动资源管理)语句块从 Java 7 开始引入,但 Groovy 并不支持。相反,Groovy 提供多种基于闭包的方法,效果相同但却合乎习惯。例如:
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
可以写成下面这样的代码:
new File('/path/to/file').eachLine('UTF-8') {
println it
}
或者,如果你想让它更接近于 Java 的惯用形式,可以这样写:
new File('/path/to/file').withReader('UTF-8') { reader ->
reader.eachLine {
println it
}
}
㈣ Java序列化问题和Groovy在Java中使用的问题
proxy对象是不能序列化的,就算能序列化也不能反序列化,因为proxy对象的类是动态生成出来的,序列化后,反序列化时目标jVM肯定没有加载过这个代理类。
有个变通的方法,就是获取到对象本身,序列化;反序列化后获取到原对象,再重新用代理包装即可获得反序列化后的代理对象了。不知道是否贴题。下面有个例子,虽然没有序列化和反序列化,但是基本实现了获取对象本身这个功能,希望能帮到你。
另外groovy对象也是java对象,应该仍然保持groovy对象本身(个人理解,groovy我也是略懂皮毛),spring应该不会对对象本身动刀子,最多加层代理啥的。
//-------------------------------------------------------------------------------
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test implements TestInterface{
public static void main(String[] args) {
final Test t = new Test();
TestInterface t2 = (TestInterface) Proxy.newProxyInstance(
Test.class.getClassLoader(),
Test.class.getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(t, args);
} catch(InvocationTargetException ite) {
throw ite.getTargetException();
}
}
}
);
t2.test();
//使用这种方式获取原对象,序列化原对象后,反序列化原对象 重新构造代理
System.out.println(t2.getThis().getClass());
System.out.println(t2.getClass());
}
public void test() {
System.out.println(1);
}
public Test getThis() {
return this;
}
}
interface TestInterface{
public void test() ;
public Test getThis() ;
}
㈤ groovy中使java必须import吗
第一种是调用groovy官方库里的类
第二种是调用自己写的groovy文本的类
缺点: 如果不安装groovy解释器和groovy Eclipse插件.就无法享受更多的对jdk 类的扩展, 已经脚本化语法的便捷.
脚本语言特点 无main,直接printf
第二步: jar依赖,maven库上传.
第三步: 推广成员安装groovy解释器和groovy Eclipse插件
1. 第一种. 如果用maven的话
在pom的 依赖项里加入.
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.2.2</version>
</dependency>
或者去官网下载grovvy的jar包,导入的eclipse的class依赖中.
就可以直接在java里调用 grovvy库里的类了.
( 如果Eclipse不会自动 import groovy的类,需要在.project中新增 <nature>org.eclipse.jdt.groovy.core.groovyNature</nature>)
import groovy.util.GroovyCollections;
import java.util.List;
public static void main(String[] args) {
List<Double> lists = new ArrayList<Double>();
lists.add(0.2);
lists.add(0.3);
lists.add(0.2);
Object sum = GroovyCollections.sum(lists);
System.out.println(sum);
}
====
2 第二种. 如果是自己写的groovy 文件.
假如如下 GrovvySystemConfigRead.groovy代码
[java]view plain
/**
*CreatedbyIntelliJIDEA.
*User:Web-03
*Date:11-4-21
*Time:下午3:43
*TochangethistemplateuseFile|Settings|FileTemplates.
*/
classGrovvySystemConfigRead{
/*
*读取邮件验证访问路径,ConfigurationHolder是groovy框架grais里的某个类
*/
staticString getName(){
return"csdn" ;
}
}
2.1 第一种调用,JAVA类(JavaClassCallGroovy)是可以直接调用GROOVY类(上面写好的SystemConfigRead)的。
(需要安装eclipse插件,自动把groovy文本文件编译为.class ,插件安装见
[java]view plain
public class JavaClassCallGroovy{
public static void main(String[] args) {
SystemConfigRead.getName();
}
}
2.2 第二种,以反射脚本化方式调用(不推荐),实现脚本化调用,即脚本改动后,无需编译,自动执行的目的.
这种反射化调用不仅可以用在java类调用groovy类,也可以用在java类调用java类,实现java的脚本化.
[java]view plain
/**
*JAVA调用GROOVY
*@throwsIOException
*@throwsIllegalAccessException
*@throwsInstantiationException
*添加人:**
*添加时间:211-08-3014:27
*/
publicvoidgroovyToJava()throwsIOException,IllegalAccessException,InstantiationException{
ClassLoaderparent=getClass().getClassLoader();
GroovyClassLoaderloader=newGroovyClassLoader(parent);
//找到指定的groovy类
ClassgroovyClass=loader.parseClass(newFile("site/grails-app/utils/com/ingping/core/SystemConfigRead.groovy"));
//将对象实例化并且强制转换为GroovyObject对象
GroovyObjectgroovyObject=(GroovyObject)groovyClass.newInstance();
//readEmailCodeUrl方法名,null参数值,没有为null
System.out.println(""+groovyObject.invokeMethod("readEmailCodeUrl",null));
}