JDK框架简析–java.lang包中的基础类库、基础数据类型
最后更新于:2022-04-01 20:12:02
# 题记
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](https://jdk7.java.net/source.html)
# 本节内容
在本节中,简析java.lang包所包含的基础类库,当我们新写一个class时,这个package里面的class都是被默认导入的,所以我们不用写import java.lang.Integer这样的代码,我们依然使用Integer这个类,当然,如果你显示写了import java.lang.Integer也没有问题,不过,何必多此一举呢![大笑](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-19_569e21abc5518.gif)
# 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](http://m.blog.csdn.net/blog/aaa1117a8w5s6d/8254922)
Java如何实现Swap功能:[http://segmentfault.com/q/1010000000332606](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/](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
';