Skip to content

Commit ac2cf11

Browse files
authored
Merge pull request giantray#73 from AcceptedBoy/master
【add】How do you assert that a certain exception is thrown in JUnit 4 tests? + and so on
2 parents 5ebf821 + 4631058 commit ac2cf11

5 files changed

+274
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
## 如何使用maven把项目及其依赖打包为可运行jar包
2+
3+
#### 问题
4+
5+
我想把java项目打包为可运行的分布式jar包。我该怎样做,才能把项目中maven所依赖的jar包导入到我的项目jar包中?
6+
7+
#### 回答
8+
9+
`pom.xml`文件中,加入如下的插件:
10+
11+
```xml
12+
<build>
13+
<plugins>
14+
<plugin>
15+
<artifactId>maven-assembly-plugin</artifactId>
16+
<configuration>
17+
<archive>
18+
<manifest>
19+
<!-- 这里是你的项目main函数所在的类的全限定名 -->
20+
<mainClass>fully.qualified.MainClass</mainClass>
21+
</manifest>
22+
</archive>
23+
<descriptorRefs>
24+
<descriptorRef>jar-with-dependencies</descriptorRef>
25+
</descriptorRefs>
26+
</configuration>
27+
</plugin>
28+
</plugins>
29+
</build>
30+
```
31+
32+
之后,运行maven命令:
33+
34+
> mvn clean compile assembly:single
35+
36+
`clean`,`compile`,`assembly:single`任务将会依次被执行;`compile`任务必须写在`assembly:single`之前,否则打包后的jar包内将不会有你的编译代码。
37+
38+
(译注:执行完后,会在你的maven项目的target目录下,生成想要的jar包,而不再需要使用`mvn package`命令进行打包)
39+
40+
通常情况下,上述maven命令执行后会自动绑定到项目的构建阶段,从而保证了以后在执行`mvn install`命令时的jar包也会被构建。
41+
(译注:下面是实际上完整的默认的`pom.xml`配置,只不过`<executions>`可以被省略,若省略则按照下述默认的配置执行)
42+
43+
```xml
44+
<plugin>
45+
<artifactId>maven-assembly-plugin</artifactId>
46+
<configuration>
47+
<archive>
48+
<manifest>
49+
<mainClass>fully.qualified.MainClass</mainClass>
50+
</manifest>
51+
</archive>
52+
<descriptorRefs>
53+
<descriptorRef>jar-with-dependencies</descriptorRef>
54+
</descriptorRefs>
55+
</configuration>
56+
<executions>
57+
<execution>
58+
<id>make-assembly</id> <!-- 用于maven继承项目的聚合 -->
59+
<phase>package</phase> <!-- 绑定到package阶段 -->
60+
<goals>
61+
<goal>single</goal>
62+
</goals>
63+
</execution>
64+
</executions>
65+
</plugin>
66+
```
67+
68+
#### 拓展
69+
70+
怎样去运行打包后的可运行jar包?
71+
72+
* 对上述配置中已经指定了`main`函数所在类的jar包,打开命令行窗口,输入命令:
73+
74+
```java
75+
java -jar jar包的路径/jar包的名字.jar
76+
```
77+
78+
例如:
79+
80+
```Auto
81+
java -jar D:\my_java_project\maven_test.jar
82+
```
83+
84+
* 若在pom.xml并没有指定`main`方法所在类,那么该jar的运行应采取如下命令:
85+
86+
```java
87+
java -cp jar包的路径/jar包的名字.jar main方法所在类的全限定名
88+
```
89+
90+
例如:
91+
92+
```java
93+
java -cp D:\my_java_project\maven_test.jar com.my.path.MainClass
94+
```
95+
96+
97+
#### StackOverflow地址
98+
99+
[http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven](http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## 如何让IntelliJ编辑器永久性显示代码行数
2+
3+
#### 问题
4+
5+
如何让IntelliJ编辑器永久性显示代码行数
6+
7+
#### 回答
8+
9+
##### <Strong>IntelliJ 14.0之后的版本</strong>
10+
11+
打开软件的菜单`File`->`Settings`->`Editor`->`General`->`Appearance`,在右侧的配置`Show line numbers`打勾:
12+
![image1][1]
13+
14+
##### <Strong>IntelliJ 8.1.2 - 13.X的版本</strong>
15+
16+
打开软件的菜单`File`->`Settings`->`Editor`->`Appearance`,在右侧的配置`Show line numbers`打勾:
17+
![images2][2]
18+
19+
#### 拓展
20+
21+
[IntelliJ IDEA 使用教程](http://www.phperz.com/article/15/0923/159068.html)
22+
23+
#### StackOverflow地址
24+
25+
http://stackoverflow.com/questions/13751/how-can-i-permanently-have-line-numbers-in-intellij
26+
27+
28+
[1]: http://i.stack.imgur.com/9DL9q.png
29+
[2]: http://i.stack.imgur.com/JVZlJ.jpg
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
## JUnit4如何断言确定异常的抛出
2+
3+
#### 问题
4+
5+
在JUnit4单元测试中,我要怎样做才能测试出有特定的异常抛出?我能想到的就只有下面的方法:
6+
7+
```java
8+
@Test
9+
public void testFooThrowsIndexOutOfBoundsException() {
10+
boolean thrown = false;
11+
12+
try {
13+
foo.doStuff();
14+
} catch (IndexOutOfBoundsException e) {
15+
thrown = true;
16+
}
17+
18+
assertTrue(thrown);
19+
}
20+
```
21+
22+
#### 回答1
23+
24+
在JUnit4后支持下面的写法:
25+
```java
26+
@Test(expected=IndexOutOfBoundsException.class)
27+
public void testIndexOutOfBoundsException() {
28+
ArrayList emptyList = new ArrayList();
29+
Object o = emptyList.get(0);
30+
}
31+
```
32+
(译者:在`@Test`注解内提供了`expected`属性,你可以用它来指定一个`Throwble`类型,如果方法调用中抛出了这个异常,那么这条测试用例就相当于通过了)
33+
34+
#### 回答2
35+
36+
如果你使用的是JUnit4.7,你可以使用如下的期望异常规则来验证异常信息:
37+
38+
```java
39+
public class FooTest {
40+
@Rule
41+
public final ExpectedException exception = ExpectedException.none();
42+
43+
@Test
44+
public void doStuffThrowsIndexOutOfBoundsException() {
45+
Foo foo = new Foo();
46+
47+
exception.expect(IndexOutOfBoundsException.class);
48+
foo.doStuff();
49+
}
50+
}
51+
```
52+
53+
这种方式比`@Test(expected=IndexOutOfBoundsException.class)`要更好,如果是在调用`foo.doStuff()`方法之前就已经抛出异常的话,测试结果就不是我们想要的了。
54+
(译者:同时,`ExpectedException`还能够验证异常信息,如`exception.expectMessage("there is an exception!");`
55+
56+
#### 拓展阅读
57+
58+
1. [JUnit:使用ExpectedException进行异常测试](http://www.tuicool.com/articles/ANviIz)
59+
2. [JUnit4 用法详解](http://www.blogjava.net/jnbzwm/archive/2010/12/15/340801.html)
60+
61+
#### StackOverflow地址:
62+
63+
[http://stackoverflow.com/questions/156503/how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests](http://stackoverflow.com/questions/156503/how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
## 如何创建泛型java数组
2+
3+
#### 问题
4+
5+
数组是不能通过泛型创建的,因为我们不能创建不可具体化的类型的数组。如下面的代码:
6+
7+
```java
8+
public class GenSet<E> {
9+
private E a[];
10+
11+
public GenSet() {
12+
a = new E[INITIAL_ARRAY_LENGTH]; //编译期就会报错:不能创建泛型数组
13+
}
14+
}
15+
```
16+
17+
#### 采纳答案
18+
19+
* 检查:强类型。`GenSet`明确知道数组中包含的类型是什么(例如通过构造器传入`Class<E>`,当方法中传入类型不是`E`将抛出异常)
20+
21+
```java
22+
public class GenSet<E> {
23+
24+
private E[] a;
25+
26+
public GenSet(Class<E> c, int s) {
27+
// 使用原生的反射方法,在运行时知道其数组对象类型
28+
@SuppressWarnings("unchecked")
29+
final E[] a = (E[]) Array.newInstance(c, s);
30+
this.a = a;
31+
}
32+
33+
E get(int i) {
34+
return a[i];
35+
}
36+
37+
//...如果传入参数不为E类型,那么强制添加进数组将会抛出异常
38+
void add(E e) {...}
39+
}
40+
```
41+
42+
* 未检查:弱类型。数组内对象不会有任何类型检查,而是作为Object类型传入。
43+
44+
在这种情况下,你可以采取如下写法:
45+
46+
```java
47+
public class GenSet<E> {
48+
49+
private Object[] a;
50+
51+
public GenSet(int s) {
52+
a = new Object[s];
53+
}
54+
55+
E get(int i) {
56+
@SuppressWarnings("unchecked")
57+
final E e = (E) a[i];
58+
return e;
59+
}
60+
}
61+
```
62+
63+
上述代码在编译期能够通过,但因为泛型擦除的缘故,在程序执行过程中,数组的类型有且仅有`Object`类型存在,这个时候如果我们强制转化为`E`类型的话,在运行时会有`ClassCastException`抛出。所以,要确定好泛型的上界,将上边的代码重写一下:
64+
65+
```java
66+
public class GenSet<E extends Foo> { // E has an upper bound of Foo
67+
68+
private Foo[] a; // E 泛型在运行期会被擦除为Foo类型,所以这里使用Foo[]
69+
70+
public GenSet(int s) {
71+
a = new Foo[s];
72+
}
73+
74+
//...
75+
}
76+
```
77+
78+
#### StackOverflow地址:
79+
80+
[http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java](http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java)

contents/whats-the-difference-between-component-repository-service-annotations-in.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
#### 问题
44

5-
在spring集成的框架中,注解在类上的`@Component``@Repository``@Service`等注解能否被互换?即这些注解的区别是什么
5+
在spring集成的框架中,注解在类上的`@Component``@Repository``@Service`等注解能否被互换?或者说这些注解有什么区别
66

77
#### 回答1
88

99
引用spring的官方文档中的一段描述:
1010

11-
在Spring2.0之前的版本中,`@Repository`注解可以标记在任何的类上,用来表明该类是用来执行与数据库相关的操作(即dao对象)
11+
在Spring2.0之前的版本中,`@Repository`注解可以标记在任何的类上,用来表明该类是用来执行与数据库相关的操作(即dao对象),并支持自动处理数据库操作产生的异常
1212

1313
在Spring2.5版本中,引入了更多的Spring类注解:`@Component`,`@Service`,`@Controller``Component`是一个通用的Spring容器管理的单例bean组件。而`@Repository`, `@Service`, `@Controller`就是针对不同的使用场景所采取的特定功能化的注解组件。
1414

1515
因此,当你的一个类被`@Component`所注解,那么就意味着同样可以用`@Repository`, `@Service`, `@Controller`来替代它,同时这些注解会具备有更多的功能,而且功能各异。
1616

1717
最后,如果你不知道要在项目的业务层采用`@Service`还是`@Component`注解。那么,`@Service`是一个更好的选择。
1818

19-
就如上文所说的,`@Repository`早已被支持了在你的持久层作为一个标记可以去自动处理数据库操作产生的异常(译者注:因为原生的java操作数据库所产生的异常只用了几种,但是产生的原因却有很多种,这样对于数据库操作的报错排查造成了一定的影响;而Spring拓展了原生的持久层异常,针对不同的产生原因有了更多的异常进行描述。所以,在注解了`@Repository`的类上如果数据库操作中抛出了异常,就能对其进行处理,转而抛出的是翻译后的spring专属数据库异常)。
19+
就如上文所说的,`@Repository`早已被支持了在你的持久层作为一个标记可以去自动处理数据库操作产生的异常(译者注:因为原生的java操作数据库所产生的异常只定义了几种,但是产生数据库异常的原因却有很多种,这样对于数据库操作的报错排查造成了一定的影响;而Spring拓展了原生的持久层异常,针对不同的产生原因有了更多的异常进行描述。所以,在注解了`@Repository`的类上如果数据库操作中抛出了异常,就能对其进行处理,转而抛出的是翻译后的spring专属数据库异常,方便我们对异常进行排查处理)。
2020

2121
| 注解 | 含义 |
2222
| ------------- |:-------------:|

0 commit comments

Comments
 (0)