- 其中:@BeforeClass,@AfterClass是Junit4中新添加进去的
- 如果Run as —>Junit Test,运行含有@Test注释的方法是,那么所有注解方法都将被执行,所含的执行顺序是:
@BeforeClass ,@Before,@Test,@After,@AfterClass- 在JUnit4中,如果测试类继承了TestCase类,那么所有的Annotation都不会起作用。
import static静态导入是JDK1.5中的新特性。一般我们导入一个类都用 import com…..ClassName;而静态导入是这样:import static com…..ClassName.*;这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。
但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便
我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。
然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
JAVA中保证多线程的线程安全有两种方式:
下面主要讲一下volatile关键字,被该关键字修饰的变量,当在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
了解更多,深入理解Java内存模型(volatile关键字)
Java基础之理解Annotation
package aes_encryption;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
*
* @author Kevin Guo
*/
public class AES_Encryption {
/**
*
*/
public static void main(String[] args) {
// TODO code application logic here
String content = "test";
String password = "12345678";
//加密
System.out.println("加密前:" + content);
byte[] encryptResult = encrypt(content, password);
System.out.println("加密后:" + encryptResult);
//解密
byte[] decryptResult = decrypt(encryptResult,password);
System.out.println("解密后:" + new String(decryptResult));
}
public static byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public static byte[] decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
}
**注意:**JAVA 原生 API 中的 AES 加密只支持128位加密,如果想要用192或者256位加密,要去官网下载JCE扩展包,替换 JAVA_HOME/jdk/jre/lib/security 里面的 local_policy 和 US_export_policy,一定要注意下载包和自己的java版本的配套,我的是1.7 就要下载这个链接里面的 JCE 7 匹配 1.7版本java
import java.io.*;
public class FileIO {
private static String path = "C:/data/test.txt";
public static void main(String[] args) throws Exception {
// Read data from file located in C:/data/test.txt
try {
File f = new File(path);
InputStreamReader isr = new InputStreamReader(new FileInputStream(f));
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while(line != null) {
System.out.println(line);
line = br.readLine();
}
} catch (Exception e) {
}
// Write data to file C:/data/test.txt
try {
File f = new File("C:/data/test.txt");
if(!f.exists())
f.createNewFile();
//Attention: the boolean parm in FileWriter(f, true) decesides if it overwrite the contents in the txt file.
BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
bw.write("This is line 1\r\n");
bw.write("This is line 2\r\n");
bw.write("This is line 3\r\n");
bw.write("This is line 4\r\n");
bw.write("This is line 5\r\n");
bw.write("This is line 6\r\n");
bw.flush();
bw.close();
} catch (Exception e) {
}
}
}
json-smart 是 java 方便操作 JSONObject 的 API 。可以方便地把自定义的 class 与 JSONObject 之间进行转化,并将转化后的 JSONObject 转换为字符串。同时该包还提供了 JSON 的解析器。
官方文档
具体使用参考这篇文档:json-smart 使用示例
可以从以下几个方面来看:
1.从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.所以redirect等于客户端向服务器端发出两次request,同时也接受两次response。
2.从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据. redirect:不能共享数据.
redirect不仅可以重定向到当前应用程序的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源.
forward 方法只能在同一个Web应用程序内的资源之间转发请求。forward 是服务器内部的一种操作. redirect是服务器通知客户端,让客户端重新发起请求.
所以,你可以说 redirect 是一种间接的请求, 但是你不能说”一个请求是属于forward还是redirect “
3.从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
4.从效率来说 forward:高. redirect:低.