分类 Java 相关 下的文章

关于 java Phantom Reference 的一些参考文章

Java 里面有4种Reference types, 从强到若, 依次为 Strong, Soft, Weak, Phantom. 其中Java API 暴露出后三种Reference 类型在 JDK 包中. 这些Reference 类型提供了与GC程序的有限的交互.

与之对应的有4种 GC 对内存对象的Reachable:
Strong Reachable:
Soft Reachable:
Weak Reachable:
Phantom Reachable:

参考:
http://javarevisited.blogspot.com/2014/03/difference-between-weakreference-vs-softreference-phantom-strong-reference-java.html
http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/ref/Reference.html
https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
http://www.cnblogs.com/blogoflee/archive/2012/03/22/2411124.html
https://weblogs.java.net/blog/kcpeppe/archive/2011/09/29/mysterious-phantom-reference
http://stackoverflow.com/questions/1599069/have-you-ever-used-phantom-reference-in-any-project
http://java.dzone.com/articles/finalization-and-phantom

SLF4j 一些理解

  1. SLF4J 是什么?

SLF4j (Simple Logging Facade for Java) 是对常用 logging 框架进项抽象提取之后定义的一个Facade API. 当你编程的时候, 仅使用SLF4j API, 而真正部署的时候可以定义到底使用哪个具体的logging 框架. 常见的logging 框架有: java.util.logging, log4j, logback, 还有一个logging facade 叫 Jakarta Commons Logging.

  1. 如何使用SLF4j?

pom.xml (以使用maven 为例), 添加如下依赖:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.9</version>
</dependency>
  1. 为什么要用 SLF4j?

作为Application的开发者来说, 很容易定义使用哪个logging框架, 尤其是在开发的时候. 可是如果代码都开发完成了, 想改logging 框架, 就比较麻烦, 如果使用SLF4j 那么就可以在deployment的时候, 随时选择更改logging 框架, 仅仅是替换binding和logging 的框架 jar 文件.
作为Library的开发者来说, 你不能限定最终的Application的开发者使用哪个logging 框架, 所以最好使用一个SLF4j这种facade API.

  1. SLF4j 的内部是怎么实现的?

SLF4j 有三层: a) API 层, 就是这个slf4j-api-x.x.x.jar. b) binding 层, 是API和真正的logging 框架之间的adapter. c) 具体的logging 框架层.
官方的架构图如下:
请输入图片描述
logback 是 SLF4j的亲儿子, 所以它是 binding层和具体的logging 框架层合一的, 都在 logback-core 和 logback-classic 这2个jar 文件中.

  1. 其它

如果你想把现有的原代码迁移到 SLF4j, 可以使用他们提供的这个 迁移工具
如果你想把现有的二进制代码里面的使用的非SLF4j的代码也改成使用SLF, 看 这里

  1. SLF4j 和 JCL 的实现区别?

SLF4j 使用 static binding 方式, 它的binding 发现是通过 ClassLoader 查找 org.slf4j.impl.StaticLoggerBinder 类, 然后加载, 找到对应的binding. 这个类是在 api jar中定义的, 却不在这个jar 里面, 而分布在具体的binding jar 里面, 当 SLF4j 第一次初始化的时候, 它会在系统查找, 如果没有发现这个类, 就默认为是 NOP (No Operation), 如果找到一个这个类, 就使用这个binding, 如果找到多个, 就使用算法算出使用具体哪个.

另外, 它避免了JCL的 class loader issue, 提供了参数化的log msg 参数.

Java 语言的 Exception

定义:
An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.

类继承关系:
Object
--Throwable .............................. 鼻祖, 所有 exception 的祖先
----Error .................................... 程序外部问题, 无法预期, 不可恢复
----Exception ............................. 除 RuntimeException 外, 都可预期, 可恢复
------RuntimeException ............. 程序内部问题, 无法预期, 不可恢复

不可预期的 Error 和 RuntimeException 都是不强制需要 try 或 throws 声明捕获的.
除了 Error 和 RuntimeException, 及其之类之外, 都需要 try 或 throws 声明捕获, 包括 throw 的 Throwable.

Error 和 RuntimeException, 及其子类被认为是 unchecked exception, 其他被认为是 checked exception, checked exception 都必须被声明捕获.

除了 try-catch-finally 块之外, Java SE 7 引入了 try-with-resources 语句, 这种新的语句特别使用于可以 Closeable 的 resources. 凡是实现 java.io.Closeable 接口的对象, 都可以通过这种语句来自动 close resource;

try (BufferedReader br = new BufferedReader(new FileReader("a.txt"))) {
    br.readLine();
}

当然 try 后面的括号中可以 声明多个 resource, 用;分开就行.
同时, 它仍然还可以跟 catch, finally 块.

Java SE 7 还引入了下面的语句:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

一般的try语句, 必须有 catch 或者 finally 跟随, 但是 try-with-resource 语句之后, 就不必了.