标签:就是 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