JDK框架简析--java.lang包中的基础类库、基础数据类型
题记
JDK。Java Development Kit。
我们必须先认识到,JDK不过,不过一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含量来说。还是在一个层级上,它们都是须要被编译成字节码。在JRE中执行的,JDK编译后的结果就是jre/lib下的rt.jar,我们学习使用它的目的是加深对Java的理解,提高我们的Java编码水平。
本系列全部文章基于的JDK版本号都是1.7.16。
源代码下载地址:https://jdk7.java.net/source.html
本节内容
在本节中,简析java.lang包所包括的基础类库。当我们新写一个class时,这个package里面的class都是被默认导入的,所以我们不用写import java.lang.Integer这种代码,我们依旧使用Integer这个类。当然。假设你显示写了import java.lang.Integer也没有问题,只是,何必多此一举呢
Object
默认全部的类都继承自Object。Object没有Property,仅仅有Method,其方法大都是native方法(也就是用其它更高效语言,通常是c实现好了的),
Object没有实现clone(),实现了hashCode(),哈希就是对象实例化后在堆内存的地址。用“==”比較两个对象,实际就是比較的内存地址是否是一个。也就是hashCode()是否相等,
默认情况下,对象的equals()方法和==符号是一样的,都是比較内存地址,可是有些对象重写了equals()方法,比方String,使其达到比較内容是否同样的效果
另外两个方法wait()和notify()是和多线程编程相关的,多线程里面synchronized实际就是加锁,默认是用this当锁,当然也能够用不论什么对象当锁。wait()上锁,线程堵塞,notify()开锁。收到这个通知的线程执行。下面代码演示样例:
class Test implements Runnable
{ private String name;
private Object prev;
private Object self; public Test(String name,Object prev,Object self)
{
this.name=name;
this.prev = prev;
this.self = self;
} @Override
public void run()
{
int count = 2;
while(count>0)
{
synchronized(prev)
{
synchronized(self)
{
System.out.println(name+":"+count);
count--;
self.notify(); //self解锁
}
try
{
prev.wait(); //prev上锁
} catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
} public static void main(String[] args) throws Exception
{
Object a = new Object();
Object b = new Object();
Object c = new Object();
Test ta = new Test("A",c,a);
Test tb = new Test("B",a,b);
Test tc = new Test("C",b,c); new Thread(ta).start();
Thread.sleep(10);
new Thread(tb).start();
Thread.sleep(10);
new Thread(tc).start();
}
}
以上代码将顺序输出:A:2、B:2、C:2、A:1、B:1、C:1 。
Object类占用内存大小计算:http://m.blog.csdn.net/blog/aaa1117a8w5s6d/8254922
Java怎样实现Swap功能:http://segmentfault.com/q/1010000000332606
构造函数和内部类
构造函数不能继承,是默认调用的。假设不显示用super指明的话,默然是调用的父类中没有參数的构造函数。
class P {
public P() {System.out.println("P");}
public P(String name) {System.out.println("P" + name);}
}
class S extends P {
public S(String name) {
super("pname"); //只是不指定的话。默认是调用的父类的没有參数的构造函数
System.out.println("name");
}
}
关于内部类。在应用编程中较少用到,可是JDK源代码中大量使用,比方Map.Entry。ConcurrentHashMap,ReentrantLock等,enum本身也会被编译成static final修饰的内部类。
关于内部类的很多其它内容,能够參阅这篇文章:http://android.blog.51cto.com/268543/384844/
Class和反射类
Java程序在执行时每一个类都会相应一个Class对象。能够从Class对象中得到与类相关的信息,Class对象存储在方法区(又名Non-Heap,永久代),当我们执行Java程序时,假设载入的jar包许多,大于指定的永久代内存大小时,则会报出PermGen错误,就是Class对象的总计大小,超过永久代内存的缘故。
Class类很实用,在我们做类型转换时常常常使用到。比方曾经用Thrift框架时,常常须要在Model类型的对象:Thrift对象和Java对象之间进行转换,须要手工书写大量模式化代码,于是,就写了个对象转换的工具,在Thrift对象和Java对象的Property名字一致的情况下。能够使用这个工具直接转换,当中大量使用了Class里面的方法和java.lang.reflect包的内容。
关于Calss类。方法众多,不详述。
以下附上这个Thrift工具的代码。
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; /**
* Thrift前缀的对象和不含Thrift前缀的对象相互转换.
* 參考:
* http://blog.csdn.net/it___ladeng/article/details/7026524
* http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html
* http://www.cnblogs.com/bingoidea/archive/2009/06/21/1507889.html
* http://java.ccidnet.com/art/3539/20070924/1222147_1.html
* http://blog.csdn.net/justinavril/article/details/2873664
*/
public class ThriftUtil {
public static final Integer THRIFT_PORT = 9177; /**
* Thrift生成的类的实例和项目原来的类的实例相关转换并赋值
* 1.类的属性的名字必须全然同样
* 2.当前支持的类型仅包含:byte,short,int,long,double,String,Date,List
* 3.假设有Specified列,则此列为true才赋值。否则,不为NULL就赋值
* @param sourceObject
* @param targetClass
* @param toThrift:true代表把JavaObject转换成ThriftObject,false代表把ThriftObject转换成JavaObject。ThriftObject中含有Specified列
* @return
*/
public static Object convert(Object sourceObject,Class<? > targetClass,Boolean toThrift)
{
if(sourceObject==null)
{
return null;
}
//对于简单类型。不进行转换,直接返回
if(sourceObject.getClass().getName().startsWith("java.lang"))
{
return sourceObject;
}
Class<?> sourceClass = sourceObject.getClass();
Field[] sourceFields = sourceClass.getDeclaredFields();
Object targetObject = null;
try {
targetObject = targetClass.newInstance();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
};
if(targetObject==null)
{
return null;
}
for(Field sourceField:sourceFields)
{
try {
//转换时过滤掉Thrift框架自己主动生成的对象
if(sourceField.getType().getName().startsWith("org.apache.thrift")
||sourceField.getName().substring(0,2).equals("__")
||("schemes,metaDataMap,serialVersionUID".indexOf(sourceField.getName())!=-1)
||(sourceField.getName().indexOf("_Fields")!=-1)
||(sourceField.getName().indexOf("Specified")!=-1)
)
{
continue;
} //处理以DotNet敏感字符命名的属性。比方operator
String sourceFieldName = sourceField.getName();
if(sourceFieldName.equals("operator"))
{
sourceFieldName = "_operator";
} else {
if(sourceFieldName.equals("_operator"))
{
sourceFieldName = "operator";
}
}
//找出目标对象中同名的属性
Field targetField = targetClass.getDeclaredField(sourceFieldName);
sourceField.setAccessible(true);
targetField.setAccessible(true);
String sourceFieldSimpleName = sourceField.getType().getSimpleName().toLowerCase().replace("integer", "int");
String targetFieldSimpleName = targetField.getType().getSimpleName().toLowerCase().replace("integer", "int");
//假设两个对象同名的属性的类型全然一致:Boolean,String,以及5种数字类型:byte,short,int,long,double,以及List
if(targetFieldSimpleName.equals(sourceFieldSimpleName))
{
//对于简单类型,直接赋值
if("boolean,string,byte,short,int,long,double".indexOf(sourceFieldSimpleName)!=-1)
{
Object o = sourceField.get(sourceObject);
if(o != null)
{
targetField.set(targetObject, o);
//处理Specified列,或者依据Specified列对数值对象赋NULL值
try
{
if(toThrift)
{
Field targetSpecifiedField = targetClass.getDeclaredField(sourceFieldName+"Specified");
if(targetSpecifiedField != null)
{
targetSpecifiedField.setAccessible(true);
targetSpecifiedField.set(targetObject, true);
}
} else {
Field sourceSpecifiedField = sourceClass.getDeclaredField(sourceFieldName+"Specified");
if(sourceSpecifiedField != null
&& "B,S,B,I,L,D".indexOf(targetField.getType().getSimpleName().substring(0,1))!=-1
)
{
sourceSpecifiedField.setAccessible(true);
if(sourceSpecifiedField.getBoolean(sourceObject)==false)
{
targetField.set(targetObject, null);
}
}
}
} catch (NoSuchFieldException e) {
//吃掉NoSuchFieldException。达到效果:假设Specified列不存在。则全部的列都赋值
}
}
continue;
}
//对于List
if(sourceFieldSimpleName.equals("list"))
{
@SuppressWarnings("unchecked")
List<Object> sourceSubObjs = (ArrayList<Object>)sourceField.get(sourceObject);
@SuppressWarnings("unchecked")
List<Object> targetSubObjs = (ArrayList<Object>)targetField.get(targetObject);
//关键的地方。假设是List类型,得到其Generic的类型
Type targetType = targetField.getGenericType();
//假设是泛型參数的类型
if(targetType instanceof ParameterizedType)
{
ParameterizedType pt = (ParameterizedType) targetType;
//得到泛型里的class类型对象。
Class<?> c = (Class<?>)pt.getActualTypeArguments()[0];
if(sourceSubObjs!=null)
{
if(targetSubObjs==null)
{
targetSubObjs = new ArrayList<Object>();
}
for(Object obj:sourceSubObjs)
{
targetSubObjs.add(convert(obj,c,toThrift));
}
targetField.set(targetObject, targetSubObjs);
}
}
continue;
}
}
//转换成Thrift自己主动生成的类:Thrift没有日期类型,我们统一要求日期格式化成yyyy-MM-dd HH:mm:ss形式
if(toThrift)
{
if(sourceFieldSimpleName.equals("date")&&targetFieldSimpleName.equals("string"))
{
Date d = (Date)sourceField.get(sourceObject);
if(d!=null)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
targetField.set(targetObject,sdf.format(d));
}
continue;
}
} else {
if(sourceFieldSimpleName.equals("string")&&targetFieldSimpleName.equals("date"))
{
String s = (String)sourceField.get(sourceObject);
if(s!=null)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
targetField.set(targetObject,sdf.parse(s));
}
continue;
}
}
//对于其它自己定义对象
targetField.set(targetObject, convert(sourceField.get(sourceObject),targetField.getType(),toThrift)); } catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} }
return targetObject;
}
}
ClassLoader
类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器 (bootstrap) 和用户自己定义装载器 (user-defined class loader) 。
JVM在执行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader.。
Bootstrap是用C++编写的,我们在Java中看不到它。是null。是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader 的 Parent 是ExtClassLoader ,而 ExtClassLoader 的 Parent 为 Bootstrap ClassLoader 。
Java 提供了抽象类 ClassLoader ,全部用户自己定义类装载器都实例化自 ClassLoader 的子类。
System Class Loader 是一个特殊的用户自己定义类装载器,由 JVM 的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类 。系统类装载器能够通过ClassLoader.getSystemClassLoader() 方法得到。
代码演演示样例如以下:
class ClassLoaderTest {
public static void main(String[] args) throws Exception{
Class c;
ClassLoader cl;
cl = ClassLoader.getSystemClassLoader();
System.out.println(cl);
while(cl != null) {
cl = cl.getParent();
System.out.println(cl);
}
c = Class.forName("java.lang.Object");
cl = c.getClassLoader();
System.out.println("java.lang.Object's loader is " + cl);
c = Class.forName("ClassLoaderTest");
cl = c.getClassLoader();
System.out.println("ClassLoaderTest's loader is " + cl);
}
}
八种基本数据类型
类类型 | 原生类型(primitive) | 代表意义 |
Boolean | boolean | 布尔 |
Character | char | 单个Unicode字符,占用两个字节,比如'a','中'。范围0-65535 |
Byte | byte | 8位有符号整型 |
Short | short | 16位有符号整型 |
Integer | int | 32位有符号整型 |
Long | long | 64位有符号整型 |
Float | float | 单精度浮点 |
Double | double | 双精度浮点 |
了解到数据类型。就要了解一点编码(数字在计算机中的01编码)的知识,计算机是用01表示全部类型的,第一位是符号位,0+1-,java中得整型都是有符号的。
对于数字,定义了原码、反码和补码。
正数的原码、反码和补码都是一样的。负数的反码是除符号位之外,全部位取反,补码是反码+1,以Byte类型为例:
能表示的数字范围是-128~127,总计256个数。对于0~127,表示为:0000000~01111111,即0~2^7-1。对于负数。-128~-1,表演示样例如以下:
-127~-1,其原码分别为11111111~10000001,换算成补码是10000001~11111111,然后10000000代表-128,-128仅仅有补码,没有原码和反码。
补码的设计目的:
使符号位能与有效值部分一起參加运算,从而简化运算规则。
补码机器数中的符号位,并非强加上去的,是数据本身的自然组成部分。能够正常地參与运算。
使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。
反码是原码与补码转换的一个中间过渡,使用较少。
全部这些转换都是在计算机的最底层进行的,而在我们使用的汇编、c等其它高级语言中使用的都是原码。
除此之外。JDK原码还常常使用>>、>>>运算符,>>是有符号移位。高位补符号位。右移。>>>是无符号移为,高位补0,右移。
关于数据类型的内存存储。例如以下描写叙述一下:
原生类型,比方int i = 3,不论是变量,还是值,都是存储在栈中的。
类类型。比方Integer i = 300,则变量是存储在栈中,对象是存储在堆中的一个对象,既然Integer是这样。那么Integer a = 300。Integer b = 300。请问 a == b。是否成立?
答案是:不成立的,由于两个对象的内存地址不同了。
既然这样,那么Integer a = 1,Integer b = 1。请问a == b。是否成立?
答案是:成立的。这事实上是Java的一个坑。我们能够看Integer对于int进行封箱操作的源代码,例如以下:
public static Integer valueOf(int i) {
if(i >= -128 && i<= IntegerCache.high)
return IntegerCache.cache[i+128];
else
return new Integer(i);
}
由此可见,对于128之内的数字。是进行了Cache存储的 。所以在堆中的内存地址是一样的,所以成立。
在编程中。能够对于数字前面加0x表示16进制数,加0表示8进制数。默认是10进制数。在数字的后面添加L表示long类型,默认是整型。对于浮点数,在后面添加F表示float类型,模式是double型。
对于类型转换,比方int i=(int)1.5,会直接把小数后面的部分去掉。对于数学函数Math.round()、Math.ceil()、Math.floor(),能够把数字想象成0为水平线,负数在水平线下,正数在水平线上,ceil是转换成天花板,floor是转换成地板。round()是四舍五入,等于+0.5之后求floor。
String
String a = "abc",String b = "abc"。a == b是成立的。这是String的编译时优化,对于字符串常量。在内存中仅仅存一份(JDK6是存储在“方法区”的“执行时常量区”,JDK7是存储在堆中);
我们对于String进一步分析:
String a = "a" + "b" + "c"。String b = "abc",a == b依旧是成立的。原理同上;
String t = "a"。String a = t + "b" + "c"。String b = "abc"。则a == b是不成立的,由于对于变量,编译器无法进行编译时优化;可是a.intern() == b是成立的,由于当调用intern()方法时,是到执行时常量池中找值相对的对象。找到了b。所以a.intern() == b。
final String t = "a",String a = t + "b" + "c",String b = "abc",则a == b是成立的。由于final是不能够又一次赋值的,编译器能够进行编译时优化;
对于String s = a + b这种操作,每次操作,都会在堆中开辟一块内存空间。所以对于频繁大量的字符操作,性能低。所以对于大量字符操作。推荐使用的StringBuffer和StringBuilder。当中StringBuffer是线程安全的,StringBuilder是1.5版本号新加的。是非线程安全的。
实现36进制加法。及字符串替换代码演示
public class RadixAndReplace {
public static void main(String[] args) {
//1.36进制加法(不同意使用字符串总体转换为10进制再相加的办法,所以仅仅能按位加)
System.out.println(add("ZZ","ZZZ"));
System.out.println(add("3A","2"));
//2.替换字符串(考虑替换之后符合要求的情况,仅仅用一次循环)
System.out.println(replace("acbd"));
System.out.println(replace("abcd"));
}
//36进制加法
public static String add(String s1,String s2) {
int l1 = s1.length(),l2 = s2.length();
int maxLength = l1 > l2 ? l1 : l2;
int carrybit = 0; //进位
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < maxLength ; i++) {
int r1 = i < l1 ? convertToNumber(s1.charAt(s1.length()-1-i)) : 0;
int r2 = i < l2 ? convertToNumber(s2.charAt(s2.length()-1-i)) : 0;
String r = convertToString(r1 + r2 + carrybit);
carrybit = r.length() == 2 ? 1 : 0;
sb.append(r.charAt(r.length()-1));
}
if(carrybit == 1) {
sb.append("1");
}
return sb.reverse().toString();
}
//把字符(A-Z代表10-36,a-z代表37-72)
private static int convertToNumber(char ch)
{
int num = 0;
if(ch >= 'A' && ch <= 'Z')
num = ch - 'A' + 10;
else if(ch >= 'a' && ch <= 'z')
num = ch - 'a' + 36;
else
num = ch - '0';
return num;
}
//转换数字为36进制的字符串表示
//A的ASCII码是65,a的ASCII码是97
private static String convertToString(int n) {
if(n >= 0 && n <= 9) {
return String.valueOf(n);
}
if(n >= 10 && n <= 35) {
return String.valueOf((char)(n-10+65));
}
if(n >= 36 && n <= 71) {
return "1" + convertToString(n-36);
}
return "0";
}
//替换字符串“ac”。“b”,考虑b在ac中间的情况
public static String replace(String str) {
StringBuilder sb = new StringBuilder();
Boolean flag = false; //连续推断标志位
for(int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c == 'b') continue;
if(c == 'a') {
flag = true;
continue;
}
if(c == 'c' && flag) {
flag = false;
continue;
}
if(flag) {
sb.append('a').append(c);
} else {
sb.append(c);
}
}
return sb.toString();
}
}
异常和错误
Exception和Error都继承自Throwable对象。Exception分为两类,RuntimeException(执行时异常,unchecked)和一般异常(checked),Error是比較严重的错误。也是unchecked。
简单地讲,checked是必须用try/catch 或者throw处理的,能够在运行过程中恢复的,比方java.io.FileNotFoundException;而unchecked异常则是不须要try/catch处理的,比方java.lang.NullPointerException。
在比較流行的语言中,Java是唯一支持checked异常。要求我们必须进行处理的语言,这有利有弊。
关于异常类、错误类,在JDK中定义了非常多。用来描写叙述我们的代码可能遇到的各种类型的错误,这里不一一整理描写叙述。
UnsupportedOperationException
举个样例。例如以下:
在其它语言(比方C#)。假设一个类中,某些方法还没有完毕,可是须要提供一个名字给别人调用。我们能够先对这种方法加行代码throw new Exception("xxx");
刚用Java时,我们可能也想仅仅是给一行代码throw new Exception。这是不合理的。由于:对于非RuntimeException,必须try/catch,或者在方法名后面添加throws Exception(这导致调用这种方法的地方都要try/catch,或者throws,是不合理的);所以,对于这个功能,我们正确的做法是:throws new UnsupportedOperationException("xxx")。这个是执行时异常,unchecked。
Runtime
java.lang包里有非常多执行时环境相关的类,能够查看执行时环境的各种信息,比方内存、锁、安全、垃圾回收等等。见过例如以下钩子代码,在JVM关闭时。执行一些不好在程序计算过程中进行的资源释放工作。例如以下:
public class MongoHook { static void addCloseHook(){
Runtime.getRuntime().addShutdownHook( new Thread(){
@Override
public void run() {
MongoDBConn.destoryAllForHook() ;
}
}) ;
}
}
关于这个推出钩子,实际是java.lang包种的下面3个类配合完毕的:Runtime、Shutdown、ApplicationShutdownHooks。
多线程
Thread、Runnable、ThreadLocal等。关于多线程的很多其它知识。能够參阅。
接口
Clonable:生命式接口
Comparable:对象比較,泛型类
Appendable:
CharSequence:统一的字符串仅仅读接口,共同拥有4个方法,length()、charAt()、subSequence()、toString()。
Readable:
Iterable:迭代器
注解类
主要在java.lang.annotation包中,注解类用@interface来进行定义。注解类的作用范围能够是方法、属性、包等,作用失效能够是Source、Runtime、Class。
比方Override就是一个注解类。用来标记实现接口中定义的类,其源代码例如以下;
package java.lang;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
注解本身不做不论什么事情,仅仅是像xml文件一样起到配置作用。注解代表的是某种业务意义。spring中@Resource注解简单解析:首先解析类的全部属性,推断属性上面是否存在这个注解,假设存在这个注解。再依据搜索规则来取得这个bean,然后通过反射注入。
注解有例如以下规则:
1)全部的注解类都隐式继承于 java.lang.annotation.Annotation,注解不同意显式继承于其它的接口。
2)注解不能直接干扰程序代码的执行,不管添加或删除注解。代码都可以正常执行。
Java语言解释器会忽略这些注解,而由第三方工具负责对注解进行处理。
3)注解的成员以无入參、无抛出异常的方式声明;能够通过default为成员指定一个默认值;成员类型是受限的,合法的类型包含primitive及其封装类、String、Class、enums、注解类型,以及上述类型的数组类型;注解类能够没有成员,没有成员的注解称为标识注解。解释程序以标识注解存在与否进行对应的处理。
代码演示样例1:
package com.cl.search.utils; import java.lang.annotation.*;
import java.lang.reflect.*; public class MyAnnotationTest {
public static void main(String[] args) {
Test test = Container.getBean();
test.loginTest();
}
} @Documented
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface AnnotationTest {
public String nation() default "";
} interface IUser {
public void login();
} class ChineseUserImpl implements IUser {
@Override
public void login() {
System.err.println("用户登录! ");
}
} class EnglishUserImpl implements IUser {
@Override
public void login() {
System.err.println("User Login。");
}
} @AnnotationTest
class Test {
private IUser userdao;
public IUser getUserdao() {
return userdao;
}
@AnnotationTest(nation = "EnglishUserImpl")
public void setUserdao(IUser userdao) {
this.userdao = userdao;
}
public void loginTest() {
userdao.login();
}
} class Container {
public static Test getBean() {
Test test = new Test();
if (Test.class.isAnnotationPresent(AnnotationTest.class)) {
Method[] methods = Test.class.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
if (method.isAnnotationPresent(AnnotationTest.class)) {
AnnotationTest annotest = method.getAnnotation(AnnotationTest.class);
System.out.println("AnnotationTest(field=" + method.getName()
+ ",nation=" + annotest.nation() + ")");
IUser userdao;
try {
userdao = (IUser) Class.forName("com.cl.search.utils." + annotest.nation()).newInstance();
test.setUserdao(userdao);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
} else {
System.out.println("没有注解标记! ");
}
return test;
}
}
java.lang.ref包
java.lang.ref 是 Java 类库中比較特殊的一个包。它提供了与 Java 垃圾回收器密切相关的引用类。
这篇IBMproject师写的文章非常好:深入探讨 java.lang.ref 包。
java.lang.AutoCloseable接口
在Java7中,引入了一个新特性try-with-resource。即在try中的代码,其资源会自己主动释放,不用手工运行资源释放操作。
要求跟在try后面的资源必须实现AutoCloseable接口。否则会报变异错误,代码示比例如以下:
class CustomResource implements AutoCloseable
{
@Override
public void close() throws Exception {
System.out.println("进行资源释放操作! ");
} public static void main(String[] args) throws Exception {
try(CustomResource r = new CustomResource()) {
System.out.println("使用资源!");
}
}
}
JDK框架简析--java.lang包中的基础类库、基础数据类型的更多相关文章
- int是java.lang包中可用的类的名称
int是java.lang包中可用的类的名称(x) int为基本数据类型,不是类
- java.lang包
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.特性——不用import 2.String String x = "abc"; < ...
- java.lang包【Object类】
基本描述: (1)Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入: (2)Object类是所有Java类的祖先.每个类都使用 Obje ...
- JDK_API剖析之java.lang包
java.lang是Java语言的基础包,默认包中的所有来自动import到你写的类中.(按照字母排序) 1.AbstractMethodError 类.错误 自1.0开始有 继承自Incompati ...
- java.io包中的字节流—— FilterInputStream和FilterOutputStream
接着上篇文章,本篇继续说java.io包中的字节流.按照前篇文章所说,java.io包中的字节流中的类关系有用到GoF<设计模式>中的装饰者模式,而这正体现在FilterInputStre ...
- Java.lang包的接口解读
Java.lang包中提供了八个接口: 1.Appendable 能够被追加 char 序列和值的对象.如果某个类的实例打算接收来自 Formatter的格式化输出,那么该类必须实现 Appendab ...
- 集合框架的类和接口均在java.util包中。 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。
集合框架的类和接口均在java.util包中. 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换.
- 简单看看jdk7源码之java.lang包01
从今天开始简单开始读一遍jdk的源码,估计这个时间会很长,慢慢啃吧....(首先说一句抱歉,因为很多图都是直接百度扣的,图太多了不能为每一个图附上原版链接,不好意思!) 在网上看了很多的教程,读源码有 ...
- Java.lang 包 (包装类、String类、Math类、Class类、Object类)
Java 的核心 API(Application Programming Interface)是非常庞大的,这给开发者带来了很大的方便. java.lang 包是 Java 的核心类库,它包含了运行 ...
随机推荐
- [转]Linux命令之iconv
转自:http://lorna8023.blog.51cto.com/777608/420313 用途说明 iconv命令是用来转换文件的编码方式的(Convert encoding of given ...
- fastjson读取json配置文件
fastjson读取json配置文件: ClassLoader loader=FileUtil.class.getClassLoader(); InputStream stream=loader.ge ...
- CDH5.7Hadoop集群搭建(离线版)
用了一周多的时间终于把CDH版Hadoop部署在了测试环境(部分组件未安装成功),本文将就这个部署过程做个总结. 一.Hadoop版本选择. Hadoop大致可分为Apache Hadoop和第三方发 ...
- Educational Codeforces Round 42 (Rated for Div. 2)
A. Equator(模拟) 找权值的中位数,直接模拟.. 代码写的好丑qwq.. #include<cstdio> #include<cstring> #include< ...
- Asp.Mvc 常用
url转义 var address = "http://www.cnblog.com"; var a22 = Uri.EscapeDataString(address); var ...
- swift-新手必看的基础部分
Swift 是一门开发 iOS, OS X 和 watchOS 应用的新语言.然而,如果你有 C 或者 Objective-C 开发经验的话,你会发现 Swift 的很多内容都是你熟悉的. 常量和变量 ...
- 好用的JS数字格式化
/* *js格式化数字代码 * *value: 要格式化的数字值 *scale: 最多保留几位小数 *zeroed: 是否保留尾0 *percented: 是否转称百分比形式 * */ functio ...
- HDU1465 不容易系列之一&&HDU4535吉哥系列故事——礼尚往来
HDU1465不容易系列之一 Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加 ...
- Maximum Value(unique函数,lower_bound()函数,upper_bound()函数的使用)
传送门 在看大佬的代码时候遇到了unique函数以及二分查找的lower_bound和upper_bound函数,所以写这篇文章来记录以备复习. unique函数 在STL中unique函数是一个去重 ...
- exist not exist 分析
结果集1 结果集2: 最后连接条件 执行过程: 一行一行遍历结果集1的数据,然后结果集1中的连接条件执行子查询,如果有值返回那么在看是exist 还是not exist 在决定最后的结果集是否要要不 ...