标签:就是 format EDA uri 策略 安全策略 closeable 最好 地方
public class FinalizeAttack {
public static void main(String[] args) throws InterruptedException {
FinalizeAttack instance = null;
try {
instance = new FinalizeAttack();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("FinalizeAttack instace is: " + instance);
System.gc();
Thread.sleep(2000L);
Attacker.invoke();
}
/**
* 构造器,抛出异常
*/
public FinalizeAttack() {
System.out.println("start construct FinalizeAttack instance");
throw new IllegalStateException("construct error, exit");
}
/**
* 被攻击的方法
*/
public void sayHello() {
System.out.println("hello");
}
/**
* 被攻击的方法
*/
@Override
public void finalize() {
System.out.println("attack!");
Attacker.instance = this;
}
/**
* 攻击者
*/
private static class Attacker {
/** 静态实例 */
private static FinalizeAttack instance;
/**
* 调用被攻击对象的方法
*/
public static void invoke() {
instance.sayHello();
}
}
}
start construct FinalizeAttack instance construct error, exit FinalizeAttack instace is: null attack! hello
//使用try-finally进行关闭,对于下面这种将异常直接向上抛的方法,存在一个异常覆盖的问题:
//即如果br.readLine()、br.close()都抛出了异常,则后一个异常会抹除前一个异常,
//导致前一个异常的堆栈完全不打印,这样就没办法判断真实原因
public static String readFirstLine(String filename) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(filename));
try {
return br.readLine();
} finally {
br.close();
}
}
//使用try-with-resources进行关闭,对于将异常直接向上抛的方法,不会存在异常覆盖的问题:
//即如果br.readLine()、br.close()都抛出了异常,后一个异常会被禁止,方法抛出的是第一个异常,
//但是被禁止的异常并不是简单的被抛弃了,而是会被打印在异常堆栈中,并且标注为被禁止的异常,
//另外,还可以通过getSuppressed方法从捕获到的异常中访问到被禁止的异常。
public static String readFirstLine(String filename) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
return br.readLine();
}
}
上面的例子描述了try-with-resources在保留多个异常上的优势,这是对于异常直接被上抛的方法而言的。如果要在方法内部处理异常,try-with-resources也能带来编码简洁、清晰的好处:
//使用try-catch-finally进行关闭,对于下面这种在内部处理异常的方法,代码很繁琐
public static String readFirstLine(String filename) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filename));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
return "-1";
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
//close quietly
return "-1";
}
}
}
}
//使用try-with-resources进行关闭,对于下面这种在内部处理异常的方法,代码简单、清晰
public static String readFirstLine(String filename) {
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
return "-1";
}
}
public class MyConnection implements AutoCloseable {
/** 数据库连接 */
private Connection connection;
/** 驱动名 */
private final String driverName;
/** 连接串 */
private final String url;
/** 用户名 */
private final String username;
/** 密码 */
private final String password;
/** 是否关闭 */
private volatile boolean closed = false;
/**
* 构造函数
* @param driverName 驱动名
* @param url 连接串
* @param username 用户名
* @param password 密码
*/
public MyConnection(String driverName, String url, String username, String password) {
this.driverName = driverName;
this.url = url;
this.username = username;
this.password = password;
}
/**
* 初始化连接
* @throws Exception 连接初始化未找到驱动类或其他SQL异常
*/
public void init() throws Exception {
Class.forName(driverName);
this.connection = DriverManager.getConnection(url, username, password);
this.connection.setAutoCommit(false);
}
/**
* 执行查询
* @param sql 查询SQL语句
* @return 查询结果
* @throws Exception 查询失败抛出的SQLException
*/
public List<Map<String, String>> execQuery(String sql) throws Exception {
if (!closed) {
throw new IllegalStateException("connection has closed");
}
//其他处理
}
/**
* 执行插入/更新/删除语句
* @param formatSql 格式化SQL,使用占位符%s
* @param args 格式化sql参数
* @return 执行影响的行数
* @throws Exception 执行失败抛出的SQLException
*/
public int execUpdate(String formatSql, Object... args) throws Exception {
if (!closed) {
throw new IllegalStateException("connection has closed");
}
//其他处理
}
/**
* 提交事务
* @throws Exception 提交事务时失败
*/
public void commit() throws Exception {
//略
}
/**
* 关闭连接
*/
@Override
public void close() {
this.closed = true;
try {
this.connection.commit();
this.connection.close();
} catch (SQLException e) {
//close quietly
}
}
}
//FileInputStream,在简单的判断文件描述符不为null并且不为标准输入后,执行关闭
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
//FileOutputStream,在简单的判断文件描述符不为null并且不为标准输出/标准错误后,执行关闭
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}
//ThreadPoolExecutor,根据安全策略,执行shutdown关闭线程池
protected void finalize() {
SecurityManager sm = System.getSecurityManager();
if (sm == null || acc == null) {
shutdown();
} else {
PrivilegedAction<Void> pa = () -> { shutdown(); return null; };
AccessController.doPrivileged(pa, acc);
}
}
标签:就是 format EDA uri 策略 安全策略 closeable 最好 地方
原文地址:https://www.cnblogs.com/manayi/p/14651133.html