Vi
Vi是一款命令行文本编辑软件,在使用命令行工作时可以通过Vi来进行少量的文本编辑工作,避免双手离开键盘,从而提高工作效率。Vi的基本用法如下:
-
打开文件
在终端下,使用Vi打开一个文件只需要输入
Vi
+文件名。 -
查看模式
打开文件后,Vi默认处于查看模式,此时可以通过键盘的上下左右键移动光标,查看文件,假如想跳转到某一行,可以在键盘输入
:
+行号,然后回车,即可跳到那一行的开头。 -
编辑模式
在查看模式下,键盘输入
i
可以进入编辑模式,此时Vi的下方会显示INSERT
,表示已进入编辑模式,编辑模式可以对文件进行修改。 -
离开编辑模式
在编辑模式下按
Esc
键可以离开编辑模式,回到查看模式。 -
保存文件&退出Vi
在查看模式下可以退出Vi,有以下几种方法,在键盘输入:
:q
:退出Vi,不保存对文件的修改。:wq
:退出Vi,并保存对文件的修改。:q!
:强制退出Vi,不保存对文件的修改。:wq!
:强制退出Vi,并保存对文件的修改。之所以要使用
!
强制退出,是因为有时候Vi会输出警告,输入q
或者wq
都无法退出,比如下面的情况:
这个时候要键入:q!
或者:wq!
才能退出Vi。
JAVA
Java包含的知识很多,这两天我主要学习了Java关于包的知识。在同一个目录下,一个java文件可以直接引用另一个java文件的类。
包的定义
如果这些java文件不在同一个目录,或者属于不同的功能的话,就要使用包对它们进行管理。由于相同目录下一个java文件可以直接引用另一个java文件的类,因此每个包的java文件都在同一个目录内,因此包也可以看做是一个文件夹,包里面包含了与这个包有关的所有java文件。
- 假如有一个包叫做
com.github.hk
,包里面有一个源文件名为sample.java
,那么这个源文件的位置就应该是PROJECT_ROOT/com/github/hk/sample.java
。
导入包
要导入一个包中的java文件,我们就要在java文件的顶部声明如下的语句:
import packagename.javafile
即java文件前面要加上包的名字。假如想导入一个包中的所有文件,可以使用以下语句:
import packagename.*
编译包
如果想要编译整个包,可以在终端使用以下的语句:
$ javac -d DEST_DIR package.*
其中DEST_DIR
是放置.class
文件的目录,使用这种方式编译出来的.class
文件会保持java文件一样的包结构。比如现在有一个包叫Test
,包里面有A.java
、B.java
两个文件,使用以下语句编译:
$ javac -d src Test.*
编译成功后,src
目录里就会有一个Test
目录,里面有A.class
和B.class
两个文件。
权限修饰符
在java中,类的权限修饰符的权限如下:
同一个类 | 同一个包不同类 | 不同包的子类 | 不同包的无关类 | |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
default | Y | Y | N | N |
private | Y | N | N | N |
其中Y代表可以访问,N代表不能访问。比如同一个类中的其他函数可以访问权限为private
的函数/变量,但是同一个包不同类的函数不能访问其他类的private
函数/变量。
Ant
在我的理解中,Ant就是java版的Makefile,只不过Ant支持更多的服务/工具。Ant文件使用XML文件来定义。在本次实训中,需要学习的Ant知识点如下:
-
框架
因为Ant文件是XML文件,因此在文件头要先定义XML文件的版本:
<?xml version="1.0"?>
然后要定义我们的
project
名和默认情况下生成的target
,如:<project name="Hello World Project" default="build"> ... ... ... </project>
比如这里的
project
名为Hello World Project
,默认target
为build
,关于target
怎么定义下文会提到 -
属性
Ant文件中的属性可以理解为变量。其定义方式如下:
<property name="Age" value="18"/>
其中"Age"就是这个属性的名字,"18"就是这个属性的值。假如想访问这个属性:
<echo>age is ${Age}</echo>
使用
${property name}
的方式即可。 -
数据类型
-
文件集
<fileset dir="src"> <include name="*.java"/> </fileset>
以上的文件集
fileset
数据类型选择了src
文件夹中所有的java文件。 -
模式集合
一个模式集合
patternset
指的是使用一种模式过滤文件/文件夹,原理类似于正则表达式。- ?:匹配一个或零个字符
- *:匹配零个或者多个字符
- **:递归地匹配零个或者多个目录
<patternset id="java.files.without.stubs"> <include name="src/**/*.java"/> <exclude name="src/**/*Stub*"/> </patternset>
比如以上的模式可以递归匹配
src
文件夹下所有文件名中不带有Stub
的java文件。模式集合可以和文件集结合使用,如:
<fileset dir="src"> <patternset refid="java.files.without.stubs"/> </fileset>
以上的文件集引用了
java.files.without.stubs
这个模式。 -
文件列表
文件列表
filelist
类似于文件集,只不过内容是固定的,不能使用通配符。<filelist id="java.files" dir="src"> <file name="A.java"/> <file name="B.java"/> </filelist>
比如以上的文件列表就指定了
src
文件夹中的A.java
文件和B.java
文件。 -
路径
路径
path
可以选择多条路径,和文件集、文件列表等数据类型结合:<path id="build.classpath.jar"> <pathelement path="src"/> <fileset dir="lib"> <include name="**/*.jar"/> </fileset> </path>
其中
pathelement
指向单个的路径。fileset
指向一个文件集合。这个path
指向src
目录以及lib
目录下的所有.jar
文件。
-
-
目标生成
目标生成的语法和Makefile文件的原理类似,看下面例子:
<target name="build" depend="prepare"> <mkdir dir="${build.dir}"/> <javac srcdir="${src.dir}" destdir="${build.dir}" debug="true"/> <javac srcdir="${test.dir}" destdir="${build.dir}" debug="true"/> </target>
这个目标名为
build
,要生成build
,必须先生成目标的依赖prepare
。首先为编译后的.class
文件创建目录${build.dir}
。然后使用javac语句将${src.dir}
目录的文件全部编译,将编译后的结果保存到${build.dir}
,debug="true"
表示输出debug信息。 -
清空编译文件
清空编译文件类似于Makefile的
make clean
,例子如下:<target name="clean"> <delete> <fileset dir="${build.dir}"> <include name="*.class"/> </fileset> </delete> </target>
使用
<delete>
语句把文件集的内容全部删除。
Junit
Junit是java下一个进行单元测试的框架,我使用的版本是3.8,因此主要讲解Junit3.8的用法。使用Junit进行测试时,被测试类和测试类要放在一个包内。这里以一个典型的测试类结构讲解Junit的用法:
import junit.framework.TestCase;
import junit.framework.Assert;
public class Test extends TestCase{
static private HelloWorld test = new HelloWorld();
@Override
public void setUp() {
// called before test
}
@Override
public void tearDown() {
// called after test
}
public void testmytest1() {
Assert.assertEquals("hello", test.hello());
}
public void testmytest2() {
Assert.assertEquals("hello", "test.hello()");
}
}
首先,测试类需要继承junit.framework.TestCase
类。然后要重载setUp()
和tearDown()
函数,这两个函数分别在单元测试前和单元测试后被调用。
-
单元测试函数
在测试类中,每个单元测试函数的类型必须是
public void
,且不能带有参数。测试函数名要以test
开头,可以使用Assert.assertEquals()
函数进行测试,这个函数的作用是判断输入的两个值是否相同,相当于assert()
。在测试类中,因为单元测试函数不能带参数,可以将被测试类声明为私有类(如同HelloWorld
类),然后对其进行测试。 -
调用Junit
我选择了使用Ant来调用Junit,因为Ant支持Junit服务。例子如下:
<target name="junit" depends="build"> <junit printsummary="true"> <classpath refid="compile.path"/> <test name="Test"/> </junit> </target>
使用
<junit>
语句,对特定路径的文件进行测试,<test name="Test">
用于声明测试类。因为调用Junit是直接调用.class
文件,因此需要先编译文件,使用<depends="build">
声明Junit测试要依赖于build
目标的生成。