文章目录
自学Java
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。—— [ 百度百科 ]
因此一开始入门并不会很困难,主要的与C++不同之处是Java是真正的面向对象编程,甚至直接将main函数封装在一个类中。
(1)HelloWorld
在Java中HelloWorld类是这样写的:
public class HelloWorld {
public String str_ = null;
public String str(HelloWorld A) {
return str_;
}
public HelloWorld() {
str_ = "HelloWorld\n";
}
/*
public static void main(String[] args){
System.out.print("Hello, World!");
}
*/
}
从上面我们不难看到main被封装在一个类中充当一个函数,然后再一个是Java向控制台输出数据的方式与C++不一样,Java主要提供了三种方法:
-
print(输出项):实现不换行输出。输出项可以是变量名、常量、表达式。
-
println(输出项):输出数据后换行。输出项可以是变量名、常量、表达式。
-
printf("格式控制部分”,表达式1,表达式2,…表达式n):格式控制部分由“格式控制符”+“普通字符组成”。普通字符原样输出;常用的格式控制符有:
(1): 与C语言 一样的:
- %d(代表十进制数)
- %c(代表一个字符)
- %f(代表浮点数)
- %f(代表浮点数)
- %e(代表科学计数法的浮点数)
- %s(代表字符串)
- %n(代表换行符)
(2): 输出时也可以控制数据的宽度:
- %md:输出的int型数组占m列
- %.nf:输出的浮点型数据小数部分保留n位
(2)Calculator小程序
Ⅰ学习GUI
主要是要使用到与界面,即GUI有关的包,所以就需要对Java相关的包进行学习,这里主要学习了Swing这个包,主要参考的是java gui快速入门教程
-
JFrame 类是一个容器,允许程序员把其他组件添加到它里面,把它们组织起来,并把它们呈现给用户。
- JFrame():创建一个框架,该框架初始为不可见;
- JFrame(String title):创建一个框架,参数title为窗体标题,该框架初始为不可见;
- void setBackground(Color c):设置窗体的背景色;
- Container getContentPane():获得窗体的内容面板,当要往窗体中添加组件或设置布局时,要使用到该方法;
- void setSize(int w,int h):设置窗体的大小,参数w和h指定宽度和高度
- void setTitle(String title):以title中指定的值,设置窗体的标题
-
JPanel 是 Java图形用户界面(GUI)工具包swing中的面板容器类,包含在javax.swing 包中,可以进行嵌套,功能是对窗体中具有相同逻辑功能的组件进行组合。
- GridLayout(int rows, int cols, int hgap, int vgap) : 创建具有指定行数、列数以及组件水平、纵向一定间距的网格布局。
- FlowLayout(int align, int hgap, int vgap) : 创建一个新的流布局管理器,它具有指定的对齐方式以及指定的水平和垂直间隙。
- BorderLayout : 用来设置JPanel里面每个组件之间的四个方位之间的距离。
Ⅱ 实现计算器
思路:
-
首先应该有一个UI界面,所以就需要先设置UI界面的带下以及方位,所以就是用JFrame进行界面的大小设置:
-
接着就是设计JFrame中JPanel的JTextField以及JButton,也就是把物理层的东西做好
效果如下:
-
然后就是设计逻辑层的东西了,主要是在点击JButton的时候要实时进行反应,所以要添加一个ActionListener,用来检测每个JButton是否被点击了并做出相行的反应。同时还需要做的检测是:
- 当OK被点击的时候,要判断两个输入的数字是否合法,因为有可能会是字符串。
- 当OK被点击的时候,还需要判断op操作符是否为空,为空则不进行相应的操作。
- 当操作符是/号的时候,要判断被除数会不会是0,是0则报错。
Ant 与 Junit 的学习
(1)Ant
只要使用过Linux系统的读者,应该知道 make这个命令。当编译Linux内核及一些软件的源程序时,经常要用这个命令。Make命令其实就 是一个项目管理工具,而Ant所实现功能与此类似。像make,gnumake和nmake这些编译工具都有 一定的缺陷,但是Ant却克服了这些工具的缺陷。最初Ant开发者在开发跨平台的应用时,同样也 是基于这些缺陷对Ant做了更好的设计。—— [ 百度百科 ]
-
ant是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,大多用在Java环境中的软件开发。
-
<\?xml version="1.0" ?>
说明版本号为1.0的XML文档。 -
<project></project>
Ant的根元素- name:用于指定project元素的名称
- default:用于指定project默认执行时所执行的target的名称
- basedir:用于指定基路径的位置。该属性没有指定时,使用
-
<target></target>
为ant的基本执行单元或是任务,它可以包含一个或多个具体的单元/任务。多个target 可以存在相互依赖关系- name :指定 target 元素的名称,这个属性在一个 project 元素中是唯一的。我们可以通过-指定 target 元素的名称来指定某个 target 。
- depends :用于描述 target 之间的依赖关系,若与多个 target 存在依赖关系时,需要以“,”间隔。 Ant 会依照 depends 属性中 target 出现的顺序依次执行每个 target ,被依赖的target 会先执行。
- if :用于验证指定的属性是存在,若不存在,所在 target 将不会被执行。
- unless :该属性的功能与 if 属性的功能正好相反,它也用于验证指定的属性是否存在,若不存在,所在 target 将会被执行。
- description :该属性是关于 target 功能的简短描述和说明。
-
<property />
property元素可看作参量或者参数的定义,project 的属性可以通过 property 元素来设定,也可在 Ant 之外设定。 -
<copy />
主要用来对文件和目录的复制功能 -
<delete />
对文件或目录进行删除 -
<move />
移动文件或目录 -
<echo>
该任务的作用是根据日志或监控器的级别输出信息。- message 、file 、append 、level
-
<jar>
- destfile表示JAR文件名。
- basedir表示被归档的文件名。
- includes表示别归档的文件模式。
- exchudes表示被排除的文件模式。
- compress表示是否压缩。
-
<javac />
该标签用于编译一个或一组java文件- srcdir表示源程序的目录。
- destdir表示class文件的输出目录。
- include表示被编译的文件的模式。
- excludes表示被排除的文件的模式。
- classpath表示所使用的类路径。
- debug表示包含的调试信息。
- optimize表示是否使用优化。
- verbose 表示提供详细的输出信息
- fileonerror表示当碰到错误就自动停止。
-
<java />
该标签用来执行编译生成的.class文件,其属性如下。- classname 表示将执行的类名。
- jar表示包含该类的JAR文件名。
- classpath所表示用到的类路径。
- fork表示在一个新的虚拟机中运行该类。
-failonerror表示当出现错误时自动停止。 - output 表示输出文件。
- append表示追加或者覆盖默认文件。
用Eclipse完成的Ant程序如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. --><project basedir="." default="build" name="helloworld">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../../usr/lib/eclipse"/>
<property name="junit.output.dir" value="junit"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.5"/>
<property name="source" value="1.5"/>
<path id="helloworld.classpath">
<pathelement location="bin"/>
<pathelement location="lib/junit-4.9.jar"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="helloworld.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
<target name="Helloworld (1)">
<java classname="helloworld.Helloworld" failonerror="true" fork="yes">
<classpath refid="helloworld.classpath"/>
</java>
</target>
<target name="New_configuration">
<mkdir dir="${junit.output.dir}"/>
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml"/>
<classpath refid="helloworld.classpath"/>
</junit>
</target>
<target name="HelloWorldTest">
<mkdir dir="${junit.output.dir}"/>
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml"/>
<test name="hello.HelloWorldTest" todir="${junit.output.dir}"/>
<classpath refid="helloworld.classpath"/>
</junit>
</target>
<target name="junitreport">
<junitreport todir="${junit.output.dir}">
<fileset dir="${junit.output.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${junit.output.dir}"/>
</junitreport>
</target>
</project>
(2)Junit单元测试
JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。—— [ 百度百科 ]
Ⅰ常用annotation
- @Before:初始化方法,在任何一个测试执行之前必须执行的代码;
- @After:释放资源,在任何测试执行之后需要进行的收尾工作。在每个测试方法执行之后执行一次,只能修饰public void 方法;
- @Test:测试方法,表明这是一个测试方法。在Junit中将会自动被执行。只能修饰public void 方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。
- @Ignore:忽略的测试方法,标注的含义就是“某些方法尚未完成,暂不参与此次测试”;这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。
- @BeforeClass:针对所有测试,只执行一次,且必须为public static void;
- @AfterClass:针对所有测试,将会在所有测试方法执行结束后执行一次,且必须为public static void;
所以一个Junit 4 的单元测试用例执行顺序为:@BeforeClass –> @Before –> @Test –> @After –> @AfterClass;每一个测试方法的调用顺序为:@Before –> @Test –> @After。
Ⅱ HelloWorld 的Junit测试代码
package hello;
import org.junit.Test;
public class HelloWorldTest {
public HelloWorld A = new HelloWorld();
@Test
public void test(){
System.out.print(A.str(A));
}
}
而Junit与Ant的结合只需要在build.xml中加一个<target name="junitreport">
<target name="junitreport">
<junitreport todir="${junit.output.dir}">
<fileset dir="${junit.output.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${junit.output.dir}"/>
</junitreport>
</target>
SonarQube
Sonar可以从以下七个维度检测代码质量,而作为开发人员至少需要处理前5种代码质量问题
- 不遵循代码标准
sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写 - 潜在的缺陷
sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具检测出潜在的缺陷 - 糟糕的复杂度分布
文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员难以理解它们
且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试 - 重复
显然程序中包含大量复制粘贴的代码是质量低下的,sonar可以展示源码中重复严重的地方 - 注释不足或者过多
没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降
而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷 - 缺乏单元测试
sonar可以很方便地统计并展示单元测试覆盖率 - 糟糕的设计
通过sonar可以找出循环,展示包与包、类与类之间的相互依赖关系,可以检测自定义的架构规则通过sonar可以管理第三方的jar包,可以利用LCOM4检测单个任务规则的应用情况, 检测耦合。
主要语法·:
./sonar.sh start 启动服务
./sonar.sh stop 停止服务
./sonar.sh restart 重启服务
需要定义的是一个叫做sonar-project.properties的文件
# require metadata
# projectKey
sonar.projectKey=src // 输入存放.java文件的文件夹
sonar.projectName=src // 输入存放.java文件的文件夹
sonar.projectVersion=1.0
sonar.sourceEncoding=UTF-8
sonar.modules=java-module
# java module
java-module.sonar.projectName=Java Module
java-module.sonar.language=java
# . projectBaseDir
java-module.sonar.sources=.
java-module.sonar.projectBaseDir=src // 输入存放.java文件的文件夹
Calculator代码测试结果:
实验总结
总的来说还是学会很多东西的,上学期本来有Java的专选课,但是因为自己选的是网页设计,所以没机会接触,这次终于能够在本地很容易得生成一个有界面的应用了,用C++写的话还十分的复杂,同时也学会了与make功能差不多的ant,还是比较容易理解ant里面每部分的功能的,还学会了用Junit对自己的代码进行测试以及Sonar对自己的代码进行质量检测,这都是比较新奇的操作,真幸运能学到,哈哈哈,虽然肝了好几天了,但还是继续加油吧!!