实战 Groovy: 构建和解析 XML

原贴地址:http://www.ibm.com/developerworks/cn/java/j-pg05199/

 

 

通过本文,您将了解使用 Groovy 分解 XML 是多么地容易。在本期的 实战 Groovy 中,作者 Scott Davis 演示了无论您是使用 MarkupBuilder  StreamingMarkupBuilder 创建 XML,还是使用 XmlParser  XmlSlurper 解析 XML,Groovy 都提供了一系列用于处理这类流行数据格式的工具。

XML 似乎已经由来已久。实际上,XML 在 2008 年迎来了它的 10 年庆典(参见 参考资料)。由于 Java™ 语言只比 XML 早几年出现,因此有人认为对于 Java 开发人员来说,XML  始终存在的。

关于本系列

Groovy 是在 Java 平台上运行的一种现代编程语言。它提供与已有 Java 代码的无缝集成,同时引入了各种生动的新特性,比如说闭包和元编程。简单来讲,Groovy 是 Java 语言的 21 世纪版本。

将任何新工具整合到开发工具包中的关键是知道何时使用它以及何时将它留在工具包中。Groovy 的功能可以非常强大,但惟一的条件是正确应用于适当的场景。因此, 实战 Groovy 系列将探究 Groovy 的实际应用,以便帮助您了解何时以及如何成功使用它们。

Java 语言创始人 Sun Microsystems 一直是 XML 的积极支持者。毕竟,XML 的平台独立性承诺能与 Java 语言的 “编写一次,随处运行” 的口号完美契合。由于这两种技术具备一些相同的特性,您可能会认为 Java 语言和 XML 能很好地相处。事实上,在 Java 语言中解析和生成 XML 不但奇特而且还复杂。

幸运的是,Groovy 引入了一些全新的、更加合理的方法来创建和处理 XML。在一些示例的帮助下(均可通过 下载 获取),本文向您展示了如何通过 Groovy 简化 XML 的构建和解析。

比较 Java 和 Groovy XML 解析

在 “for each 剖析” 的结束部分,我提供了一个如清单 1 所示的简单 XML 文档。(这次,我添加了 type 属性,稍微增加了它的趣味性。)


清单 1. XML 文档,其中列出了我知道的语言

				

  Java
  Groovy
  JavaScript

 

在 Java 语言中解析这个简单的 XML 文档却丝毫不简单,如清单 2 所示。它使用了 30 行代码来解析 5 行 XML 文件。


清单 2. 在 Java 中解析 XML 文件

				
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.IOException;

public class ParseXml {
  public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse("src/languages.xml");

      //print the "type" attribute
      Element langs = doc.getDocumentElement();
      System.out.println("type = " + langs.getAttribute("type"));

      //print the "language" elements
      NodeList list = langs.getElementsByTagName("language");
      for(int i = 0 ; i < list.getLength();i++) {
        Element language = (Element) list.item(i);
        System.out.println(language.getTextContent());
      }
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    }catch(SAXException se) {
      se.printStackTrace();
    }catch(IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

 

比较清单 2 中的 Java 代码和清单 3 中相应的 Groovy 代码:


清单 3. 在 Groovy 中解析 XML

				
def langs = new XmlParser().parse("languages.xml")
println "type = ${langs.attribute("type")}"
langs.language.each{
  println it.text()
}

//output:
type = current
Java
Groovy
JavaScript

 

Groovy 代码最出色的地方并不是它要比相应的 Java 代码简短很多 — 虽然使用 5 行 Groovy 代码解析 5 行 XML 是一个压倒性的优势。Groovy 代码最让我欣喜的一个地方就是它更具表达性。在编写 langs.language.each 时,我的感觉就像是在直接操作 XML。在 Java 版本中,您再也看不到 XML。

 




回页首


字符串变量和 XML

当您将 XML 存储在 String 变量而不是文件中时,在 Groovy 中使用 XML 的好处会变得更加明显。Groovy 的三重引号(在其他语言中通常称作 HereDoc)使得在内部存储 XML 变得非常轻松,如清单 4 所示。这与清单 3 中的 Groovy 示例之间的惟一区别就是将 XmlParser 方法调用从 parse()(它处理FileInputStreamsReader  URI)切换到 parseText()


清单 4. 将 XML 存储在 Groovy 内部

				
def xml = """

  Java
  Groovy
  JavaScript

"""

def langs = new XmlParser().parseText(xml)
println "type = ${langs.attribute("type")}"
langs.language.each{
  println it.text()
}

 

注意,三重引号可以轻松地处理多行 XML 文档。xml 变量是一个真正的普通旧式(plain-old)java.lang.String — 您可以添加 println xml.class 自己进行验证。三重引号还可以处理 type="current" 的内部引号,而不会强制您像在 Java 代码中那样使用反斜杠字符手动进行转义。

比较清单 4 中简洁的 Groovy 代码与清单 5 中相应的 Java 代码:


清单 5. 在 Java 代码内部存储 XML

				
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;

public class ParseXmlFromString {
  public static void main(String[] args) {
    String xml = "\n" +
            "  Java\n" +
            "  Groovy\n" +
            "  JavaScript\n" +
            "";

    byte[] xmlBytes = xml.getBytes();
    InputStream is = new ByteArrayInputStream(xmlBytes);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(is);

      //print the "type" attribute
      Element langs = doc.getDocumentElement();
      System.out.println("type = " + langs.getAttribute("type"));

      //print the "language" elements
      NodeList list = langs.getElementsByTagName("language");
      for(int i = 0 ; i < list.getLength();i++) {
        Element language = (Element) list.item(i);
        System.out.println(language.getTextContent());
      }
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    }catch(SAXException se) {
      se.printStackTrace();
    }catch(IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

 

注意,xml 变量受到了针对内部引号和换行符的转义字符的污染。然而,更糟的是需要将 String 转换成一个 byte 数组,然后再转换成 ByteArrayInputStream才能进行解析。DocumentBuilder 未提供将简单 String 作为 XML 解析的直观方法。

 




回页首


通过 MarkupBuilder 创建 XML

Groovy 相对 Java 语言最大的优势体现于在代码中创建 XML 文档。清单 6 显示了创建 5 行 XML 代码段所需的 50 行 Java 代码:


清单 6. 使用 Java 代码创建 XML

				
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

public class CreateXml {
  public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.newDocument();

      Element langs = doc.createElement("langs");
      langs.setAttribute("type", "current");
      doc.appendChild(langs);

      Element language1 = doc.createElement("language");
      Text text1 = doc.createTextNode("Java");
      language1.appendChild(text1);
      langs.appendChild(language1);

      Element language2 = doc.createElement("language");
      Text text2 = doc.createTextNode("Groovy");
      language2.appendChild(text2);
      langs.appendChild(language2);

      Element language3 = doc.createElement("language");
      Text text3 = doc.createTextNode("JavaScript");
      language3.appendChild(text3);
      langs.appendChild(language3);

      // Output the XML
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
      StringWriter sw = new StringWriter();
      StreamResult sr = new StreamResult(sw);
      DOMSource source = new DOMSource(doc);
      transformer.transform(source, sr);
      String xmlString = sw.toString();
      System.out.println(xmlString);
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    } catch (TransformerConfigurationException e) {
      e.printStackTrace();
    } catch (TransformerException e) {
      e.printStackTrace();
    }
  }
}

 

我知道一些人会立刻抱怨。许多第三方库都可以简化此代码 — JDOM 和 dom4j 是其中最流行的两个。但是,任何 Java 库都无法与使用 GroovyMarkupBuilder 的简洁性相比,如清单 7 所示:


清单 7. 使用 Groovy 创建 XML

				
def xml = new groovy.xml.MarkupBuilder()
xml.langs(type:"current"){
  language("Java")
  language("Groovy")
  language("JavaScript")
}

 

注意到这与 XML 代码的比率又重新回到了将近 1:1。更加重要的是,我可以再次查看 XML。当然,尖括号已经被替换为大括号,并且属性使用冒号(Groovy 的 HashMap 符号)而不是等号,但其基本结构在 Groovy 或 XML 中都是可以辨认的。它几乎类似于一个用于构建 XML 的 DSL,您认为呢?

Groovy 能够实现这种 Builder 魔法,因为它是一种动态的语言。另一方面,Java 语言则是静态的:Java 编译器将确保所有方法在您调用它们之前都是确实存在的。(如果您尝试调用不存在的方法,Java 代码甚至不进行编译,更不用说运行了。)但是,Groovy 的 Builder 证明,某种语言中的 bug 正是另一种语言的特性。如果您查阅 API 文档中的 MarkupBuilder 相关部分,您会发现它没有 langs() 方法、language() 方法或任何其他元素名称。幸运的是,Groovy 可以捕获这些不存在的方法调用,并采取一些有效的操作。对于 MarkupBuilder 的情况,它使用 phantom 方法调用并生成格式良好的 XML。

清单 8 对我刚才给出的简单的 MarkupBuilder 示例进行了扩展。如果您希望在 String 变量中捕获 XML 输出,则可以传递一个 StringWriter MarkupBuilder 的构造函数中。如果您希望添加更多属性到 langs 中,只需要在传递时使用逗号将它们分开。注意,language 元素的主体是一个没有前置名称的值。您可以在相同的逗号分隔的列表中添加属性和主体。


清单 8. 经过扩展的 MarkupBuilder 示例

				
def sw = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(sw)
xml.langs(type:"current", count:3, mainstream:true){
  language(flavor:"static", version:"1.5", "Java")
  language(flavor:"dynamic", version:"1.6.0", "Groovy")
  language(flavor:"dynamic", version:"1.9", "JavaScript")
}
println sw

//output:

  Java
  Groovy
  JavaScript

 

通过这些 MarkupBuilder 技巧,您可以实现一些有趣的功能。举例来说,您可以快速构建一个格式良好的 HTML 文档,并将它写出到文件中。清单 9 显示了相应的代码:


清单 9. 通过 MarkupBuilder 构建 HTML

				
def sw = new StringWriter()
def html = new groovy.xml.MarkupBuilder(sw)
html.html{
  head{
    title("Links")
  }
  body{
    h1("Here are my HTML bookmarks")
    table(border:1){
      tr{
        th("what")
        th("where")
      }
      tr{
        td("Groovy Articles")
        td{
          a(href:"http://ibm.com/developerworks", "DeveloperWorks")
        }
      }
    }
  }
}

def f = new File("index.html")
f.write(sw.toString())

//output:

  
    Links
  
  
    

Here are my HTML bookmarks

what where
Groovy Articles DeveloperWorks

 

图 1 显示了清单 9 所构建的 HTML 的浏览器视图:


图 1. 呈现的 HTML
呈现的 HTML 




回页首


使用 StreamingMarkupBuilder 创建 XML

MarkupBuilder 非常适合用于同步构建简单的 XML 文档。对于更加高级的 XML 创建,Groovy 提供了一个 StreamingMarkupBuilder。通过它,您可以添加各种各样的 XML 内容,比如说处理指令、名称空间和使用 mkp 帮助对象的未转义文本(非常适合 CDATA 块)。清单 10 展示了有趣的 StreamingMarkupBuilder特性:


清单 10. 使用 StreamingMarkupBuilder 创建 XML

				
def comment = "]]>"
def builder = new groovy.xml.StreamingMarkupBuilder()
builder.encoding = "UTF-8"
def person = {
  mkp.xmlDeclaration()
  mkp.pi("xml-stylesheet": "type='text/xsl' href='myfile.xslt'" )
  mkp.declareNamespace('':'http://myDefaultNamespace')
  mkp.declareNamespace('location':'http://someOtherNamespace')
  person(id:100){
    firstname("Jane")
    lastname("Doe")
    mkp.yieldUnescaped(comment)
    location.address("123 Main")
  }
}
def writer = new FileWriter("person.xml")
writer << builder.bind(person)

//output:



  Jane
  Doe
  ]]>
  123 Main

 

注意,StreamingMarkupBuilder 直到您调用 bind() 方法时才会生成最终的 XML,该方法将接受标记和所有指令。这允许您异步构建 XML 文档的各个部分,并同时输出它们。(参见 参考资料 了解更多信息。)

 




回页首


理解 XmlParser

Groovy 为您提供了两种生成 XML — MarkupBuilder  StreamingMarkupBuilder 的方式 — 它们分别具备不同的功能。解析 XML 也同样如此。您可以使用XmlParser 或者 XmlSlurper

XmlParser 提供了更加以程序员为中心的 XML 文档视图。如果您习惯于使用 List  Map(分别对应于 Element  Attribute)来思考文档,则应该能够适应XmlParser。清单 11 稍微解析了 XmlParser 的结构:


清单 11. XmlParser 详细视图

				
def xml = """

  Java
  Groovy
  JavaScript

"""

def langs = new XmlParser().parseText(xml)
println langs.getClass()
// class groovy.util.Node

println langs
/*
langs[attributes={type=current, count=3, mainstream=true};
      value=[language[attributes={flavor=static, version=1.5};
                      value=[Java]],
             language[attributes={flavor=dynamic, version=1.6.0};
                      value=[Groovy]],
             language[attributes={flavor=dynamic, version=1.9};
                      value=[JavaScript]]
            ]
]
*/

 

注意,XmlParser.parseText() 方法返回了一个 groovy.util.Node — 在本例中是 XML 文档的根 Node。当您调用 println langs 时,它会调用Node.toString() 方法,以便返回调试输出。要获取真实数据,您需要调用 Node.attribute() 或者 Node.text()

 




回页首


使用 XmlParser 获取属性

如前所述,您可以通过调用 Node.attribute("key") 来获取单独的属性。如果您调用 Node.attributes(),它会返回包含所有 Node 的属性的 HashMap。使用您在 “for each 剖析” 一文中所掌握的 each 闭包,遍历每个属性简直就是小菜一碟。清单 12 显示了一个相应的例子。(参见 参考资料,获取关于groovy.util.Node 的 API 文档。)


清单 12. XmlParser 将属性作为 HashMap 对待

				
def langs = new XmlParser().parseText(xml)

println langs.attribute("count")
// 3

langs.attributes().each{k,v->
  println "-" * 15
  println k
  println v
}

//output:
---------------
type
current
---------------
count
3
---------------
mainstream
true

 

与操作属性相类似,XmlParser 为处理元素提供了更好的支持。

 




回页首


使用 XmlParser 获取元素

XmlParser 提供了一种直观的查询元素的方法,称作 GPath。(它与 XPath 类似,仅在 Groovy 中得到了实现。)举例来说,清单 13 演示了我之前使用的langs.language 结构返回了包含查询结构的 groovy.util.NodeListNodeList 扩展了 java.util.ArrayList,因此它基本上就是一个赋予了 GPath 超级权限的 List


清单 13. 使用 GPath  XmlParser 进行查询

				
def langs = new XmlParser().parseText(xml)

// shortcut query syntax
// on an anonymous NodeList
langs.language.each{
  println it.text()
}

// separating the query
// and the each closure
// into distinct parts
def list = langs.language
list.each{
  println it.text()
}

println list.getClass()
// groovy.util.NodeList

 

当然,GPath 是对 MarkupBuilder 的补充。它所采用的技巧与调用不存在的 phantom 方法相同,区别仅在于它用于查询已有的 XML 而不是动态地生成 XML。

知道 GPath 查询的结果是 List 之后,您可以让您的代码更加简练。Groovy 提供了一个 spread-dot 运算符。在单行代码中,它基本上能迭代整个列表并对每个项执行方法调用。结果将作为 List 返回。举例来说,如果您只关心对查询结果中的各个项调用 Node.text() 方法,那么清单 14 展示了如何在一行代码中实现它:


清单 14. 结合 spread-dot 运算符与 GPath 

				
// the long way of gathering the results
def results = []
langs.language.each{
  results << it.text()
}

// the short way using the spread-dot operator
def values = langs.language*.text()
// [Java, Groovy, JavaScript]

// quickly gathering up all of the version attributes
def versions = langs.language*.attribute("version")
// [1.5, 1.6.0, 1.9]

 

和功能强大的 XmlParser 一样,XmlSlurper 也实现了更高级别的处理。

 




回页首


使用 XmlSlurper 解析 XML

 清单 2 中,我说过 Groovy 给我的感觉是在直接操作 XML。XmlParser 的功能相当不错,但它只允许您以编程的方式来操作 XML。您可以使用由 Node 组成的 List 以及由 Attribute 组成的 HashMap,并且仍然需要调用 Node.attribute()  Node.text() 等方法才能获取核心数据。XmlSlurper 将删除方法调用的最后痕迹,让您感觉就像是在直接处理 XML。

从技术上说,XmlParser 返回 Node  NodeList,而 XmlSlurper 返回一个 groovy.util.slurpersupport.GPathResult。但既然您已经知道,因此我希望您能忘记之前提到的 XmlSlurper 的实现细节。如果您能忽略其内部原理,那么将更好地领略其魔力。

清单 15 同时展示了一个 XmlParser 和一个 XmlSlurper


清单 15. XmlParser  XmlSlurper 

				
def xml = """

  Java
  Groovy
  JavaScript

"""

def langs = new XmlParser().parseText(xml)
println langs.attribute("count")
langs.language.each{
  println it.text()
}

langs = new XmlSlurper().parseText(xml)
println langs._cnnew1@count
langs.language.each{
  println it
}

 

注意,XmlSlurper 忽略了任何方法调用的概念。您并没有调用 langs.attribute("count"),而是调用了 langs.@count@ 符号是从 XPath 借过来的,但其结果是,您感觉像是在直接操作属性(与调用 attribute() 方法相反)。您没有调用 it.text(),而仅仅调用了 it。我们假设您希望直接操作元素的内容。

 




回页首


现实中的 XmlSlurper

除了 langs  language 之外,这里还提供了实际的 XmlSlurper 示例。Yahoo! 以 RSS 提要的方式按 ZIP 码提供天气情况信息。当然,RSS 是 XML 中的一种专门术语。在 Web 浏览器中键入 http://weather.yahooapis.com/forecastrss?p=80020。可以随意将 Broomfield, Colorado 的 ZIP 码换成您自己的。清单 16 显示了最终 RSS 提要的简单版本:


清单 16. 显示最新天气情况的 Yahoo! RSS 提要

				

  
    Yahoo! Weather - Broomfield, CO
    
    

    
      Conditions for Broomfield, CO at 7:47 am MST
      Fri, 27 Feb 2009 7:47 am MST
      
    
  

 

您要做的第一件事就是通过编程来使用这个 RSS。创建一个名称为 weather.groovy 的文件,并添加如清单 17 所示的代码:


清单 17. 以编程的方式获取 RSS

				
def baseUrl = "http://weather.yahooapis.com/forecastrss"

if(args){
  def zip = args[0]
  def url = baseUrl + "?p=" + zip
  def xml = url.toURL().text
  println xml
}else{
  println "USAGE: weather zipcode"
}

 

在命令行中键入 groovy weather 80020,确定您可以看到原始 RSS。

此脚本最重要的部分是 url.toURL().texturl 变量是一个格式良好的 String。Groovy 在所有 String 中都添加了一个 toURL() 方法,用于将它们转换成java.net.URL。然后,Groovy 在所有 URL 中又添加了一个 getText() 方法,用于执行 HTTP GET 请求并将结构作为 String 返回。

现在,您已经将 RSS 存储在了 xml 变量中,并通过 XmlSlurper 实现了一些有趣的功能,如清单 18 所示:


清单 18. 使用 XmlSlurper 解析 RSS

				
def baseUrl = "http://weather.yahooapis.com/forecastrss"

if(args){
  def zip = args[0]
  def url = baseUrl + "?p=" + zip
  def xml = url.toURL().text

  def rss = new XmlSlurper().parseText(xml)
  println rss.channel.title
  println "Sunrise: ${rss.channel.astronomy.@sunrise}"
  println "Sunset: ${rss.channel.astronomy.@sunset}"
  println "Currently:"
  println "\t" + rss.channel.item.condition.@date
  println "\t" + rss.channel.item.condition.@temp
  println "\t" + rss.channel.item.condition.@text
}else{
  println "USAGE: weather zipcode"
}

//output:
Yahoo! Weather - Broomfield, CO
Sunrise: 6:36 am
Sunset: 5:50 pm
Currently:
   Fri, 27 Feb 2009 7:47 am MST
   25
   Partly Cloudy

 

XmlSlurper 让您可以自然地处理 XML,不是吗?您通过直接引用 </code><span class="Apple-converted-space"> </span>元素来打印它 —<span class="Apple-converted-space"> </span><code>rss.channel.title</code>。您使用一个简单的<code>rss.channel.item.condition.@temp</code><span class="Apple-converted-space"> </span>来去除<span class="Apple-converted-space"> </span><code>temp</code><span class="Apple-converted-space"> </span>属性。这与编程的感觉不同。它更像是在直接操作 XML。</p> <p>您是否注意到<span class="Apple-converted-space"> </span><code>XmlSlurper</code><span class="Apple-converted-space"> </span>甚至忽略了名称空间?您在构造函数中启用名称空间感知,但我很少这样做。非常简单,<code>XmlSlurper</code><span class="Apple-converted-space"> </span>能像切黄油那样分解 XML。</p> <p> </p> <table border="0" width="100%"> <tbody> <tr> <td style="line-height:19px;"> <br></td> </tr> </tbody> </table> <table class="no-print" border="0" align="right"> <tbody> <tr align="right"> <td style="line-height:19px;"> <br> <table border="0"> <tbody> <tr> <td style="line-height:19px;" valign="middle"> <br></td> <td style="line-height:19px;" align="right" valign="top"><strong>回页首</strong></td> </tr> </tbody> </table></td> </tr> </tbody> </table> <p><br></p> <p><span class="atitle" style="font-family:Arial, sans-serif;font-size:18px;font-weight:bold;">结束语</span></p> <p>要在如今成为一名成功的开发人员,您需要一系列能简化 XML 处理的工具。Groovy 的<span class="Apple-converted-space"> </span><code>MarkupBuilder</code><span class="Apple-converted-space"> </span>和<span class="Apple-converted-space"> </span><code>StreamingMarkupBuilder</code><span class="Apple-converted-space"> </span>可以非常轻松地动态创建 XML。<code>XmlParser</code><span class="Apple-converted-space"> </span>能为您提供由<span class="Apple-converted-space"> </span><code>Element</code><span class="Apple-converted-space"> </span>组成的<span class="Apple-converted-space"> </span><code>List</code><span class="Apple-converted-space"> </span>以及由<span class="Apple-converted-space"> </span><code>Attribute</code><span class="Apple-converted-space"> </span>组成的<span class="Apple-converted-space"> </span><code>HashMap</code>,并且<span class="Apple-converted-space"> </span><code>XmlSlurper</code><span class="Apple-converted-space"> </span>可以让代码全部消失,让您感觉是在直接操作 XML。</p> <p>如果没有 Groovy 的动态功能,XML 处理的强大功能将不可能实现。在下一章文章中,</p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1175417949897437184"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Groovy)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1897016531259289600.htm" title="Windows写代码,Linux运行 (WSL & VS Code)" target="_blank">Windows写代码,Linux运行 (WSL & VS Code)</a> <span class="text-muted">ch120668</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/1.htm">开发工具</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>在工作中,很多时候都是用Linux服务器,经常是一个PuTTY或是GitBash连上去,要写一些Shell,Python,Perl,Groovy等脚本,通常也是用vi/vim/emacs/nano等常用编辑器,这些都很好用,也习惯了。有时候,当自己想要学点东西,想要配个Linux的环境,一般都是装个虚拟机(如VirtualBox),然后安装一个Ubuntu或CentOS。现在,Windows10(</div> </li> <li><a href="/article/1895404250977071104.htm" title="Spock框架:让单元测试更优雅的高效武器" target="_blank">Spock框架:让单元测试更优雅的高效武器</a> <span class="text-muted">没什么技术</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spock/1.htm">spock</a> <div>前言:为什么选择Spock?在软件开发领域,单元测试是保证代码质量的基石。但传统的JUnit/TestNG测试框架在面对复杂测试场景时,往往会显得力不从心。Spock框架作为新一代测试框架的佼佼者,以其独特的BDD(行为驱动开发)风格和GroovyDSL语法,正在成为Java/Kotlin开发者的新宠。本文将带你全面认识这个让测试代码变得优雅高效的利器!一、Spock框架初探1.1什么是Spock</div> </li> <li><a href="/article/1895371463238676480.htm" title="03-Groovy-注释、变量和数据类型" target="_blank">03-Groovy-注释、变量和数据类型</a> <span class="text-muted">爱学习de测试小白</span> <a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/groovy/1.htm">groovy</a> <div>目录前言注释变量数据类型前言本篇学习Groovy注释、变量和数据类型。注释单行注释//单行注释println('HelloGroovy')多行注释/**多行注释*print不换行打印*打印内容可用双引号,也可用单引号*可使用小括号,也可不用小括号*语句结束可写分号,也可省略*/println("换行打印")print('不换行打印----')println'不加括号和分号的打印'println'加</div> </li> <li><a href="/article/1892411162377646080.htm" title="Android Gradle使用总结" target="_blank">Android Gradle使用总结</a> <span class="text-muted">Wei_Leng</span> <a class="tag" taget="_blank" href="/search/Android/1.htm">Android</a><a class="tag" taget="_blank" href="/search/studio/1.htm">studio</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC/1.htm">脚本</a> <div>其他Groovy入门学习http://blog.csdn.net/zhaoyanjun6/article/details/70313790AndroidGradleAndroid项目使用Gradle作为构建框架,Gradle又是以Groovy为脚本语言。所以学习Gradle之前需要先熟悉Groovy脚本语言。Groovy是基于Java语言的脚本语言,所以它的语法和Java非常相似,但是具有比jav</div> </li> <li><a href="/article/1890926960708743168.htm" title="Selenium WebDriver自动化测试(扩展篇)--Jenkins持续集成" target="_blank">Selenium WebDriver自动化测试(扩展篇)--Jenkins持续集成</a> <span class="text-muted">职说测试</span> <a class="tag" taget="_blank" href="/search/selenium/1.htm">selenium</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/ci%2Fcd/1.htm">ci/cd</a><a class="tag" taget="_blank" href="/search/UI%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/1.htm">UI自动化测试</a><a class="tag" taget="_blank" href="/search/web%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/1.htm">web自动化测试</a> <div>文章目录一、引言二、Jenkins简介三、安装部署Jenkins安装部署四、集成Git与Maven安装必要的插件配置Git配置Maven五、创建Job创建自由风格的项目配置源码管理配置构建触发器配置构建环境配置构建步骤配置Post-buildActions六、触发构建示例:GitHubWebhook触发构建七、封装通用方法示例:使用Groovy脚本创建Job八、总结参考文献一、引言持续集成(Con</div> </li> <li><a href="/article/1889982974049447936.htm" title="Android Studio报错:Could not get unknown property ‘kotlin_version‘" target="_blank">Android Studio报错:Could not get unknown property ‘kotlin_version‘</a> <span class="text-muted">zhangphil</span> <a class="tag" taget="_blank" href="/search/Android/1.htm">Android</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>AndroidStudio报错:Couldnotgetunknownproperty'kotlin_version'报错内容:Causedby:groovy.lang.MissingPropertyException:Couldnotgetunknownproperty'kotlin_version'forobjectoftypeorg.gradle.api.internal其中一个解决方案,把:</div> </li> <li><a href="/article/1888782714568503296.htm" title="Groovy语言的游戏开发" target="_blank">Groovy语言的游戏开发</a> <span class="text-muted">霍璟琅</span> <a class="tag" taget="_blank" href="/search/%E5%8C%85%E7%BD%97%E4%B8%87%E8%B1%A1/1.htm">包罗万象</a><a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a> <div>Groovy语言的游戏开发之旅引言随着游戏产业的飞速发展,越来越多的开发者开始寻找更高效、更灵活的编程语言来实现他们的创意。Groovy作为一种动态的JVM语言,近些年来逐渐受到开发者的关注。本文将探讨Groovy语言在游戏开发中的应用、优势、相关框架以及如何通过实际示例来帮助开发者快速上手。Groovy语言简介Groovy是一种基于Java平台的编程语言,通常用于简化Java开发过程。它的语法相</div> </li> <li><a href="/article/1888076447185170432.htm" title="Android 使用 Kotlin 重写 Gradle 文件(1)" target="_blank">Android 使用 Kotlin 重写 Gradle 文件(1)</a> <span class="text-muted">2401_84122016</span> <a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/kotlin/1.htm">kotlin</a><a class="tag" taget="_blank" href="/search/gitee/1.htm">gitee</a> <div>}利用Kotlin可以改造成下面这样:buildTypes{getByName(“release”){isMinifyEnabled=falseproguardFiles(getDefaultProguardFile(“proguard-android-optimize.txt”),“proguard-rules.pro”)}}指定JDK改造Groovy语法的指定JDK如下所示:compileOp</div> </li> <li><a href="/article/1887058674946469888.htm" title="编程语言90种" target="_blank">编程语言90种</a> <span class="text-muted">2501_90255623</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>CC++JavaPythonJavaScriptC#PHPSQLGoTypeScriptRubySwiftKotlinRShellRustDartScalaAssemblyFortranAdaCommonLispMATLABEiffelObjective-CPerlVisualBasicHaskellErlangPrologJuliaGroovyClojureF#DOCamlRacketNimEl</div> </li> <li><a href="/article/1886446110839468032.htm" title="Groovy语言的编程范式" target="_blank">Groovy语言的编程范式</a> <span class="text-muted">沈韶珺</span> <a class="tag" taget="_blank" href="/search/%E5%8C%85%E7%BD%97%E4%B8%87%E8%B1%A1/1.htm">包罗万象</a><a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a> <div>Groovy语言的编程范式引言Groovy是一种基于JVM(JavaVirtualMachine)的动态语言,它不仅兼容Java,还提供了丰富的功能和简洁的语法,使得编程更加高效和灵活。Groovy语言结合了面向对象编程、函数式编程、并发编程等多种范式,为开发者提供了多样化的编程体验。在这篇文章中,我们将深入探讨Groovy语言的编程范式及其在实际开发中的应用。一、Groovy语言简介1.1Gro</div> </li> <li><a href="/article/1884880704551055360.htm" title="Android Gradle Kotlin DSL,使用Kotlin来构建Gradle" target="_blank">Android Gradle Kotlin DSL,使用Kotlin来构建Gradle</a> <span class="text-muted">张雨zy</span> <a class="tag" taget="_blank" href="/search/kotlin/1.htm">kotlin</a><a class="tag" taget="_blank" href="/search/Android%E5%9F%BA%E7%A1%80/1.htm">Android基础</a> <div>Demohttps://gitee.com/olleh/my-kotlin-dsl.gitGradleKotlinDSL我们现在AndroidStudio是使用Gradle来编译,而默认的构建语言是Groovy,我们可以用Kotlin来代替Groovy,Groovy构建脚本是.gradle结尾,Koltin构建的脚本则是.gradle.kts结尾优势:节约Groovy的学习成本错误提示代码自动补全</div> </li> <li><a href="/article/1884700144843157504.htm" title="Groovy中的操作符重载:实现对象的自定义运算" target="_blank">Groovy中的操作符重载:实现对象的自定义运算</a> <span class="text-muted">t0_54manong</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E4%B8%AA%E4%BA%BA%E5%BC%80%E5%8F%91/1.htm">个人开发</a> <div>在编程中,操作符重载是一种强大的功能,它允许程序员为自定义的类定义操作符的行为。Groovy语言提供了非常灵活的机制来支持操作符重载,通过定义特定的方法,我们可以让对象支持各种操作符运算。本文将通过一个简单的实例,展示如何在Groovy中实现操作符重载。Groovy操作符重载的基本原理在Groovy中,操作符重载的核心在于定义特定的方法。这些方法与操作符一一对应,当操作符被使用时,Groovy会自</div> </li> <li><a href="/article/1884503276800503808.htm" title="使用Gradle的maven-publish插件发布快照" target="_blank">使用Gradle的maven-publish插件发布快照</a> <span class="text-muted">dnc8371</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a><a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a><a class="tag" taget="_blank" href="/search/git/1.htm">git</a> <div>我最近与Gradle一起开始了一个新项目,并决定直接参加–没有Gradle经验,没有关于Groovy的线索,没有教程,只是继续尝试直到可行。在我决定使用孵化式maven-publish插件将快照发布到Sonatype的Maven快照存储库之前,这一切进展得令人惊奇,这确实令人信服。警告:正如我说的那样,我在Groovy和Gradle中都是菜鸟,所以不要相信我所说的话。我为您写下来的一切。最后(但仍</div> </li> <li><a href="/article/1884217168971755520.htm" title="Jenkins pipeline共享库的最佳实践" target="_blank">Jenkins pipeline共享库的最佳实践</a> <span class="text-muted">DevOps探索者</span> <a class="tag" taget="_blank" href="/search/Jenkins/1.htm">Jenkins</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>Jenkins共享库使用教程Jenkins共享库(SharedLibraries)是一个功能强大的工具,旨在帮助团队在多个Jenkins项目中重用代码。这使得CI/CD流水线能够更加高效、简洁,并减少重复劳动。通过共享库,你可以将常用的Groovy脚本、步骤、函数等提取到一个公共的位置,使得多个项目都能引用它们。1.什么是Jenkins共享库?Jenkins共享库是一个包含可以在多个Jenkins</div> </li> <li><a href="/article/1880736761013923840.htm" title="Jenkins-Pipeline简述" target="_blank">Jenkins-Pipeline简述</a> <span class="text-muted">xiao-xiang</span> <a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>一.什么是Jenkinspipeline:pipeline在jenkins中是一套插件,主要功能在于,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。Pipeline的实现方式是一套GroovyDSL,任何发布流程都可以表述为一段Groovy脚本(jenkinsfile),并且Jenkins支持从代码库直接读取脚本。二.关于pipeline:1.相关概念:Ste</div> </li> <li><a href="/article/1880156807389835264.htm" title="AndroidStudio Ladybug中编译完成apk之后定制名字kts复制到指定目录" target="_blank">AndroidStudio Ladybug中编译完成apk之后定制名字kts复制到指定目录</a> <span class="text-muted">debug_cat</span> <a class="tag" taget="_blank" href="/search/AndroidStudio/1.htm">AndroidStudio</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/studio/1.htm">studio</a> <div>背景编译完release版本后复制apk到特定目录,apk文件名字符合自己的需求,例如增加版本号,版本名字。翻了一遍网上基本上都是Groovy编写,但是项目刚好切换到kts了,之前Groovy代码用不了。下面是kts版本。kts适配全部代码如下,只需要在你的主模块的android中增加代码即可。android{/其他代码applicationVariants.all{valvariant=this</div> </li> <li><a href="/article/1879820914556727296.htm" title="groovy性能测试,groovy和java性能对比" target="_blank">groovy性能测试,groovy和java性能对比</a> <span class="text-muted">lilili啊啊啊</span> <a class="tag" taget="_blank" href="/search/groovy/1.htm">groovy</a><a class="tag" taget="_blank" href="/search/groovy%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94/1.htm">groovy性能对比</a><a class="tag" taget="_blank" href="/search/groovy%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">groovy性能测试</a> <div>看groovy的接口和api很神奇的,想用用,用之前做了个小的性能测试,结果令人目瞪口呆classMain{staticmain(args){defstart=System.currentTimeMillis();for(inti=1;i<100000000;i++){Math.sin(1.5);}defend=System.currentTimeMillis();printlnend-start</div> </li> <li><a href="/article/1834778982680195072.htm" title="Groovy -> Groovy 流程控制语句" target="_blank">Groovy -> Groovy 流程控制语句</a> <span class="text-muted">Yang-Never</span> <a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a><a class="tag" taget="_blank" href="/search/idea/1.htm">idea</a> <div>判断语句defx=10if(x>0){println"xispositive"}elseif(x0)?"positive":"non-positive"printlnresult//输出"positive"//log"positive"分支语句//分支语句判断数据类型defcheckType(value){switch(value){caseInteger:println"Thevalueisan</div> </li> <li><a href="/article/1834778984429219840.htm" title="Groovy -> Groovy 集合操作" target="_blank">Groovy -> Groovy 集合操作</a> <span class="text-muted">Yang-Never</span> <a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a><a class="tag" taget="_blank" href="/search/idea/1.htm">idea</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>List的增删改查[1,2,3,4][1,2,3,4,5,6][2,3,4][3,4][1,2,3,4][3,4,10][3,4,20]Element:3Element:4Element:20contains3//log[1,2,3,4][1,2,3,4,5,6][2,3,4][3,4][1,2,3,4][3,4,10][3,4,20]Element:3Element:4Element:20con</div> </li> <li><a href="/article/1832566135942377472.htm" title="Groovy入门基础" target="_blank">Groovy入门基础</a> <span class="text-muted">winton_by</span> <a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/Gradle/1.htm">Gradle</a><a class="tag" taget="_blank" href="/search/Android/1.htm">Android</a> <div>文章目录基本概念环境搭建下载groovy的manSDK(Macos)安装groovy下载IDEA配置groovyHelloWorldGroovy语法精讲文件结构变量类型字符串‘xx’"xx"'''xx'''闭包(类似java8中的lambda表达式)必包的使用场景数据结构列表列表转数组列表排序数组映射(map)范围类动态添加属性&方法(很神奇)Json操作xml操作总结Android的学习过程中,</div> </li> <li><a href="/article/1832562600467066880.htm" title="IntelliJ IDEA 中安装 Groovy 插件 && 添加 Groovy SDK" target="_blank">IntelliJ IDEA 中安装 Groovy 插件 && 添加 Groovy SDK</a> <span class="text-muted">秋夫人</span> <a class="tag" taget="_blank" href="/search/intellij-idea/1.htm">intellij-idea</a><a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a> <div>一、在IntelliJIDEA中安装Groovy插件可以按照以下步骤进行:打开IntelliJIDEA:启动IntelliJIDEA。打开插件市场:进入File->Settings(在macOS上是IntelliJIDEA->Preferences)。在左侧菜单中选择Plugins。搜索Groovy插件:在插件市场的右上角搜索框中输入Groovy。找到Groovy插件。安装插件:点击Install</div> </li> <li><a href="/article/1832546966773526528.htm" title="Groovy快速入门" target="_blank">Groovy快速入门</a> <span class="text-muted">小码快撩</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>Groovy是一种面向对象的、动态类型的、基于JVM的编程语言,它与Java高度兼容,同时引入了许多简洁、灵活的语法特性,使得开发更为高效。以下是Groovy的快速入门指南:一.环境准备1.安装JavaDevelopmentKit(JDK)Groovy是基于Java平台的语言,运行在Java虚拟机(JVM)之上,因此必须先确保系统中已安装了JDK。下载并安装适合您操作系统的最新稳定版JDK。可以从</div> </li> <li><a href="/article/1832544320998174720.htm" title="Groovy入门(有java基础)" target="_blank">Groovy入门(有java基础)</a> <span class="text-muted">black_dawn</span> <a class="tag" taget="_blank" href="/search/groovy/1.htm">groovy</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>一、基本概念Groovy是一种基于Java虚拟机(JVM)的动态开发语言,旨在扩展Java语法,提供更简洁、灵活和易于使用的编码方式。本文是在会一定java语言开发的基础上进行的对比入门学习记录。1.特点:动态性:Groovy支持动态类型和动态元编程,使得代码更加灵活和易于编写。简洁性:Groovy的语法相对于Java来说更加简洁,可以用更少的代码实现相同的功能。闭包:Groovy提供了强大的闭包</div> </li> <li><a href="/article/1827963886335258624.htm" title="Android开之AR增强现实技术ARCore组件的应用方法" target="_blank">Android开之AR增强现实技术ARCore组件的应用方法</a> <span class="text-muted">cdesigner</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/ar/1.htm">ar</a> <div>ARCore是Google提供的用于Android设备的AR平台,它提供了许多组件和功能,用于实现增强现实(AR)应用。以下是使用ARCore组件的应用方法和代码示例:配置ARCore环境:在项目的build.gradle文件中,添加ARCore库的依赖项:groovydependencies{  implementation'com.google.ar:core:1.24.0'}在应用启动时,需</div> </li> <li><a href="/article/1830239223190482944.htm" title="Gradle介绍和下载" target="_blank">Gradle介绍和下载</a> <span class="text-muted">上善若泪</span> <div>1Gradle1.1介绍gradle和maven一样都是用来构建java程序的,maven2004年开始兴起,gradle2012年开始诞生,既然已经有了maven这么成熟的构建工具为什么还有gradle的诞生呢,因为gradle有很多地方比maven做的更好,例如gradle采用groovy语言开发,语法更加简单,例如maven一个配置需要三行,而gradle只需要一行即可Gradle是继Mav</div> </li> <li><a href="/article/1772035760141172736.htm" title="最新版android stuido加上namespace" target="_blank">最新版android stuido加上namespace</a> <span class="text-muted">修行者对666</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/studio%E9%85%8D%E7%BD%AE%E9%97%AE%E9%A2%98/1.htm">studio配置问题</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>每个Android模块都有一个命名空间,此命名空间用作其生成的命名空间由模块的build.gradle文件中的namespace属性定义,如以下代码段所示。namespace最初会设为您在创建项目时选择的软件包名称。KotlinGroovyandroid{namespace"com.example.myapp"...}在将应用构建为最终应用软件包(APK)时,Android构建工具会将命名空间用作</div> </li> <li><a href="/article/1761141719023276032.htm" title="UE5 打包安卓报错LogPlayLevel: UAT: at org.codehaus.groovy.vmplugin.v7.Java7" target="_blank">UE5 打包安卓报错LogPlayLevel: UAT: at org.codehaus.groovy.vmplugin.v7.Java7</a> <span class="text-muted">htwzl</span> <a class="tag" taget="_blank" href="/search/ue5/1.htm">ue5</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%8D%93/1.htm">安卓</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>LogPlayLevel:UAT:atjava.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)LogPlayLevel:UAT:atorg.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.ru</div> </li> <li><a href="/article/1759827281502629888.htm" title="pipeline 语法及常见DSL" target="_blank">pipeline 语法及常见DSL</a> <span class="text-muted">wuleijack</span> <div>jenkinspipeline是jenkins实现持续集成持续部署最核心的部分,pipeline编写2种脚本式和声明式(官方推荐)声明式主要的需要的语法pipeline{agent{}options{}envirment{}stages{stage('build'){steps{script{}}}}}其实脚本式和声明可以相互转换所谓脚本式默认就是groovy脚本当然也可以把脚本写在script中</div> </li> <li><a href="/article/1759573664543633408.htm" title="【Java】电子凭证-Java生成PDF" target="_blank">【Java】电子凭证-Java生成PDF</a> <span class="text-muted">hkk666123</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/HTML/1.htm">HTML</a><a class="tag" taget="_blank" href="/search/%E8%BD%AC/1.htm">转</a><a class="tag" taget="_blank" href="/search/PDF/1.htm">PDF</a><a class="tag" taget="_blank" href="/search/htmlTOPDF/1.htm">htmlTOPDF</a> <div>文章目录背景实现思路技术方案图TemplateEngines(模板引擎)`Thymeleaf``ApacheFreemarker``GroovyTemplates``velocity``HTMLTOPDF`技术各实现对比表WKhtmlTOpdfiTextPhantomJS技术核心:HTML生成PDF背景在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等。方</div> </li> <li><a href="/article/1759548708988481536.htm" title="Android Weekly Notes #430" target="_blank">Android Weekly Notes #430</a> <span class="text-muted">圣骑士wind</span> <div>AndroidWeeklyIssue#430SuperchargeAndroiddevwithScrcpyandADBWIFI这个工具:https://github.com/Genymobile/scrcpy#get-the-app可以把物理设备投屏到电脑上.GradlekotlinDSL把gradle脚本从groovy迁移到kotlin.20AndroidDevToolsYou’veProbab</div> </li> <li><a href="/article/52.htm" title="解读Servlet原理篇二---GenericServlet与HttpServlet" target="_blank">解读Servlet原理篇二---GenericServlet与HttpServlet</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/HttpServlet/1.htm">HttpServlet</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%90%86/1.htm">源理</a><a class="tag" taget="_blank" href="/search/GenericService/1.htm">GenericService</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%A0%81/1.htm">源码</a> <div>在上一篇《解读Servlet原理篇一》中提到,要实现javax.servlet.Servlet接口(即写自己的Servlet应用),你可以写一个继承自javax.servlet.GenericServletr的generic Servlet ,也可以写一个继承自java.servlet.http.HttpServlet的HTTP Servlet(这就是为什么我们自定义的Servlet通常是exte</div> </li> <li><a href="/article/179.htm" title="MySQL性能优化" target="_blank">MySQL性能优化</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div>        性能优化是通过某些有效的方法来提高MySQL的运行速度,减少占用的磁盘空间。性能优化包含很多方面,例如优化查询速度,优化更新速度和优化MySQL服务器等。本文介绍方法的主要有:         a.优化查询         b.优化数据库结构   </div> </li> <li><a href="/article/306.htm" title="ThreadPool定时重试" target="_blank">ThreadPool定时重试</a> <span class="text-muted">dai_lm</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/ThreadPool/1.htm">ThreadPool</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/timer/1.htm">timer</a><a class="tag" taget="_blank" href="/search/timertask/1.htm">timertask</a> <div>项目需要当某事件触发时,执行http请求任务,失败时需要有重试机制,并根据失败次数的增加,重试间隔也相应增加,任务可能并发。 由于是耗时任务,首先考虑的就是用线程来实现,并且为了节约资源,因而选择线程池。 为了解决不定间隔的重试,选择Timer和TimerTask来完成 package threadpool; public class ThreadPoolTest { </div> </li> <li><a href="/article/433.htm" title="Oracle 查看数据库的连接情况" target="_blank">Oracle 查看数据库的连接情况</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/oracle+%E8%BF%9E%E6%8E%A5/1.htm">oracle 连接</a> <div>首先要说的是,不同版本数据库提供的系统表会有不同,你可以根据数据字典查看该版本数据库所提供的表。 select * from dict where table_name like '%SESSION%'; 就可以查出一些表,然后根据这些表就可以获得会话信息 select sid,serial#,status,username,schemaname,osuser,terminal,ma</div> </li> <li><a href="/article/560.htm" title="类的继承" target="_blank">类的继承</a> <span class="text-muted">朱辉辉33</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>类的继承可以提高代码的重用行,减少冗余代码;还能提高代码的扩展性。Java继承的关键字是extends 格式:public class 类名(子类)extends 类名(父类){ } 子类可以继承到父类所有的属性和普通方法,但不能继承构造方法。且子类可以直接使用父类的public和 protected属性,但要使用private属性仍需通过调用。 子类的方法可以重写,但必须和父类的返回值类</div> </li> <li><a href="/article/687.htm" title="android 悬浮窗特效" target="_blank">android 悬浮窗特效</a> <span class="text-muted">肆无忌惮_</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>最近在开发项目的时候需要做一个悬浮层的动画,类似于支付宝掉钱动画。但是区别在于,需求是浮出一个窗口,之后边缩放边位移至屏幕右下角标签处。效果图如下:   一开始考虑用自定义View来做。后来发现开线程让其移动很卡,ListView+动画也没法精确定位到目标点。   后来想利用Dialog的dismiss动画来完成。   自定义一个Dialog后,在styl</div> </li> <li><a href="/article/814.htm" title="hadoop伪分布式搭建" target="_blank">hadoop伪分布式搭建</a> <span class="text-muted">林鹤霄</span> <a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a> <div>要修改4个文件    1: vim hadoop-env.sh  第九行    2: vim core-site.xml            <configuration>     &n</div> </li> <li><a href="/article/941.htm" title="gdb调试命令" target="_blank">gdb调试命令</a> <span class="text-muted">aigo</span> <a class="tag" taget="_blank" href="/search/gdb/1.htm">gdb</a> <div>原文:http://blog.csdn.net/hanchaoman/article/details/5517362   一、GDB常用命令简介   r run 运行.程序还没有运行前使用 c             cuntinue </div> </li> <li><a href="/article/1068.htm" title="Socket编程的HelloWorld实例" target="_blank">Socket编程的HelloWorld实例</a> <span class="text-muted">alleni123</span> <a class="tag" taget="_blank" href="/search/socket/1.htm">socket</a> <div>public class Client { public static void main(String[] args) { Client c=new Client(); c.receiveMessage(); } public void receiveMessage(){ Socket s=null; BufferedRea</div> </li> <li><a href="/article/1195.htm" title="线程同步和异步" target="_blank">线程同步和异步</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/%E7%BA%BF%E7%A8%8B%E5%90%8C%E6%AD%A5/1.htm">线程同步</a><a class="tag" taget="_blank" href="/search/%E5%BC%82%E6%AD%A5/1.htm">异步</a> <div>多线程和同步 : 如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法   多线程和异步:多线程可以做不同的事情,涉及到线程通知     &</div> </li> <li><a href="/article/1322.htm" title="JSP中文乱码分析" target="_blank">JSP中文乱码分析</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/%E4%B8%AD%E6%96%87%E4%B9%B1%E7%A0%81/1.htm">中文乱码</a> <div>        在JSP的开发过程中,经常出现中文乱码的问题。         首先了解一下Java中文问题的由来:         Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,</div> </li> <li><a href="/article/1449.htm" title="js实现页面跳转重定向的几种方式" target="_blank">js实现页面跳转重定向的几种方式</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/%E9%87%8D%E5%AE%9A%E5%90%91/1.htm">重定向</a> <div>        js实现页面跳转重定向有如下几种方式: 一.window.location.href <script language="javascript"type="text/javascript"> window.location.href="http://www.baidu.c</div> </li> <li><a href="/article/1576.htm" title="【Struts2三】Struts2 Action转发类型" target="_blank">【Struts2三】Struts2 Action转发类型</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/struts2/1.htm">struts2</a> <div> 在【Struts2一】 Struts Hello World http://bit1129.iteye.com/blog/2109365中配置了一个简单的Action,配置如下   <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configurat</div> </li> <li><a href="/article/1703.htm" title="【HBase十一】Java API操作HBase" target="_blank">【HBase十一】Java API操作HBase</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/hbase/1.htm">hbase</a> <div>Admin类的主要方法注释:   1. 创建表 /** * Creates a new table. Synchronous operation. * * @param desc table descriptor for table * @throws IllegalArgumentException if the table name is res</div> </li> <li><a href="/article/1830.htm" title="nginx gzip" target="_blank">nginx gzip</a> <span class="text-muted">ronin47</span> <a class="tag" taget="_blank" href="/search/nginx+gzip/1.htm">nginx gzip</a> <div>Nginx GZip 压缩 Nginx GZip 模块文档详见:http://wiki.nginx.org/HttpGzipModule 常用配置片段如下: gzip on; gzip_comp_level 2; # 压缩比例,比例越大,压缩时间越长。默认是1 gzip_types text/css text/javascript; # 哪些文件可以被压缩 gzip_disable &q</div> </li> <li><a href="/article/1957.htm" title="java-7.微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h1 , h2 ,判断这俩个链表是否相交" target="_blank">java-7.微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h1 , h2 ,判断这俩个链表是否相交</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div> public class LinkListTest { /** * we deal with two main missions: * * A. * 1.we create two joined-List(both have no loop) * 2.whether list1 and list2 join * 3.print the join</div> </li> <li><a href="/article/2084.htm" title="Spring源码学习-JdbcTemplate batchUpdate批量操作" target="_blank">Spring源码学习-JdbcTemplate batchUpdate批量操作</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>Spring JdbcTemplate的batch操作最后还是利用了JDBC提供的方法,Spring只是做了一下改造和封装 JDBC的batch操作: String sql = "INSERT INTO CUSTOMER " + "(CUST_ID, NAME, AGE) VALUES (?, ?, ?)"; </div> </li> <li><a href="/article/2211.htm" title="[JWFD开源工作流]大规模拓扑矩阵存储结构最新进展" target="_blank">[JWFD开源工作流]大规模拓扑矩阵存储结构最新进展</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C%E6%B5%81/1.htm">工作流</a> <div>    生成和创建类已经完成,构造一个100万个元素的矩阵模型,存储空间只有11M大,请大家参考我在博客园上面的文档"构造下一代工作流存储结构的尝试",更加相信的设计和代码将陆续推出.........     竞争对手的能力也很强.......,我相信..你们一定能够先于我们推出大规模拓扑扫描和分析系统的....</div> </li> <li><a href="/article/2338.htm" title="base64编码和url编码" target="_blank">base64编码和url编码</a> <span class="text-muted">cuityang</span> <a class="tag" taget="_blank" href="/search/base64/1.htm">base64</a><a class="tag" taget="_blank" href="/search/url/1.htm">url</a> <div>import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; </div> </li> <li><a href="/article/2465.htm" title="web应用集群Session保持" target="_blank">web应用集群Session保持</a> <span class="text-muted">dalan_123</span> <a class="tag" taget="_blank" href="/search/session/1.htm">session</a> <div>关于使用 memcached 或redis 存储 session ,以及使用 terracotta 服务器共享。建议使用 redis,不仅仅因为它可以将缓存的内容持久化,还因为它支持的单个对象比较大,而且数据类型丰富,不只是缓存 session,还可以做其他用途,一举几得啊。1、使用 filter 方法存储这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于tomcat ,而且实现的原理比较简</div> </li> <li><a href="/article/2719.htm" title="Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']" target="_blank">Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a> <div>    public function getMinLimit () {        $sql = "...";        $result = yii::app()->db->createCo</div> </li> <li><a href="/article/2846.htm" title="solr StatsComponent(聚合统计)" target="_blank">solr StatsComponent(聚合统计)</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/solr%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2/1.htm">solr聚合查询</a><a class="tag" taget="_blank" href="/search/solr+stats/1.htm">solr stats</a> <div>StatsComponent 转载请出自出处:http://eksliang.iteye.com/blog/2169134 http://eksliang.iteye.com/ 一、概述        Solr可以利用StatsComponent 实现数据库的聚合统计查询,也就是min、max、avg、count、sum的功能   二、参数</div> </li> <li><a href="/article/2973.htm" title="百度一道面试题" target="_blank">百度一道面试题</a> <span class="text-muted">greemranqq</span> <a class="tag" taget="_blank" href="/search/%E4%BD%8D%E8%BF%90%E7%AE%97/1.htm">位运算</a><a class="tag" taget="_blank" href="/search/%E7%99%BE%E5%BA%A6%E9%9D%A2%E8%AF%95/1.htm">百度面试</a><a class="tag" taget="_blank" href="/search/%E5%AF%BB%E6%89%BE%E5%A5%87%E6%95%B0%E7%AE%97%E6%B3%95/1.htm">寻找奇数算法</a><a class="tag" taget="_blank" href="/search/bitmap+%E7%AE%97%E6%B3%95/1.htm">bitmap 算法</a> <div>那天看朋友提了一个百度面试的题目:怎么找出{1,1,2,3,3,4,4,4,5,5,5,5}  找出出现次数为奇数的数字.   我这里复制的是原话,当然顺序是不一定的,很多拿到题目第一反应就是用map,当然可以解决,但是效率不高。   还有人觉得应该用算法xxx,我是没想到用啥算法好...!   还有觉得应该先排序...   还有觉</div> </li> <li><a href="/article/3100.htm" title="Spring之在开发中使用SpringJDBC" target="_blank">Spring之在开发中使用SpringJDBC</a> <span class="text-muted">ihuning</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>  在实际开发中使用SpringJDBC有两种方式:   1. 在Dao中添加属性JdbcTemplate并用Spring注入;     JdbcTemplate类被设计成为线程安全的,所以可以在IOC 容器中声明它的单个实例,并将这个实例注入到所有的 DAO 实例中。JdbcTemplate也利用了Java 1.5 的特定(自动装箱,泛型,可变长度</div> </li> <li><a href="/article/3227.htm" title="JSON API 1.0 核心开发者自述 | 你所不知道的那些技术细节" target="_blank">JSON API 1.0 核心开发者自述 | 你所不知道的那些技术细节</a> <span class="text-muted">justjavac</span> <a class="tag" taget="_blank" href="/search/json/1.htm">json</a> <div>2013年5月,Yehuda Katz 完成了JSON API(英文,中文) 技术规范的初稿。事情就发生在 RailsConf 之后,在那次会议上他和 Steve Klabnik 就 JSON 雏形的技术细节相聊甚欢。在沟通单一 Rails 服务器库—— ActiveModel::Serializers 和单一 JavaScript 客户端库——&</div> </li> <li><a href="/article/3354.htm" title="网站项目建设流程概述" target="_blank">网站项目建设流程概述</a> <span class="text-muted">macroli</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a> <div>一.概念 网站项目管理就是根据特定的规范、在预算范围内、按时完成的网站开发任务。 二.需求分析 项目立项   我们接到客户的业务咨询,经过双方不断的接洽和了解,并通过基本的可行性讨论够,初步达成制作协议,这时就需要将项目立项。较好的做法是成立一个专门的项目小组,小组成员包括:项目经理,网页设计,程序员,测试员,编辑/文档等必须人员。项目实行项目经理制。 客户的需求说明书   第一步是需</div> </li> <li><a href="/article/3481.htm" title="AngularJs 三目运算 表达式判断" target="_blank">AngularJs 三目运算 表达式判断</a> <span class="text-muted">qiaolevip</span> <a class="tag" taget="_blank" href="/search/%E6%AF%8F%E5%A4%A9%E8%BF%9B%E6%AD%A5%E4%B8%80%E7%82%B9%E7%82%B9/1.htm">每天进步一点点</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E6%B0%B8%E6%97%A0%E6%AD%A2%E5%A2%83/1.htm">学习永无止境</a><a class="tag" taget="_blank" href="/search/%E4%BC%97%E8%A7%82%E5%8D%83%E8%B1%A1/1.htm">众观千象</a><a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a> <div>事件回顾:由于需要修改同一个模板,里面包含2个不同的内容,第一个里面使用的时间差和第二个里面名称不一样,其他过滤器,内容都大同小异。希望杜绝If这样比较傻的来判断if-show or not,继续追究其源码。 var b = "{{", a = "}}"; this.startSymbol = function(a) { </div> </li> <li><a href="/article/3608.htm" title="Spark算子:统计RDD分区中的元素及数量" target="_blank">Spark算子:统计RDD分区中的元素及数量</a> <span class="text-muted">superlxw1234</span> <a class="tag" taget="_blank" href="/search/spark/1.htm">spark</a><a class="tag" taget="_blank" href="/search/spark%E7%AE%97%E5%AD%90/1.htm">spark算子</a><a class="tag" taget="_blank" href="/search/Spark+RDD%E5%88%86%E5%8C%BA%E5%85%83%E7%B4%A0/1.htm">Spark RDD分区元素</a> <div>关键字:Spark算子、Spark RDD分区、Spark RDD分区元素数量     Spark RDD是被分区的,在生成RDD时候,一般可以指定分区的数量,如果不指定分区数量,当RDD从集合创建时候,则默认为该程序所分配到的资源的CPU核数,如果是从HDFS文件创建,默认为文件的Block数。   可以利用RDD的mapPartitionsWithInd</div> </li> <li><a href="/article/3735.htm" title="Spring 3.2.x将于2016年12月31日停止支持" target="_blank">Spring 3.2.x将于2016年12月31日停止支持</a> <span class="text-muted">wiselyman</span> <a class="tag" taget="_blank" href="/search/Spring+3/1.htm">Spring 3</a> <div>              Spring 团队公布在2016年12月31日停止对Spring Framework 3.2.x(包含tomcat 6.x)的支持。在此之前spring团队将持续发布3.2.x的维护版本。          请大家及时准备及时升级到Spring </div> </li> <li><a href="/article/3862.htm" title="fis纯前端解决方案fis-pure" target="_blank">fis纯前端解决方案fis-pure</a> <span class="text-muted">zccst</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>作者:zccst FIS通过插件扩展可以完美的支持模块化的前端开发方案,我们通过FIS的二次封装能力,封装了一个功能完备的纯前端模块化方案pure。 1,fis-pure的安装 $ fis install -g fis-pure $ pure -v 0.1.4 2,下载demo到本地 git clone https://github.com/hefangshi/f</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>