一、内省Introspector,操作标准javabean的类
---------------------------------------------------------------
/**
* 测试内省
*/
@Test
public void tsIntrospector()
{
try {
//得到java bean 的信息
BeanInfo bInfo = Introspector.getBeanInfo(Person.class);
//获取属性描述符
PropertyDescriptor[] pos = bInfo.getPropertyDescriptors();
for (PropertyDescriptor p : pos) {
//属性名称
String fieldName = p.getName();
//get方法
Method mGet = p.getReadMethod();
//set方法
Method mSet = p.getWriteMethod();
}
} catch (Exception e) {
e.printStackTrace();
}
}
二、代理
-----------------------------------------------------------------
1.代理分为静态代理和动态代理两种。
2.静态代理,代理类需要自己编写代码写成。
3.动态代理,代理类通过 Proxy.newInstance() 方法生成。
4.不管是静态代理还是动态代理,代理与被代理者都要实现两样接口,它们的实质是面向接口编程。
5.静态代理和动态代理的区别是在于要不要开发者自己定义 Proxy 类。
6.动态代理通过 Proxy 动态生成 proxy class,但是它也指定了一个 InvocationHandler 的实现类。
7.代理模式本质上的目的是为了增强现有代码的功能。
8.批处理的时候,尤其重要
---------------------------------------------------------------------------------------------
------------------------------------测试代理案例----------------------------------------
---------------------------------------------------------------------------------------------
/**
* 1.定义接口规范,被代理的基本接口
* 目标接口1
*/
public interface HelloWorldInterface
{
public void sayHello(String str);
public String sayHello1(String str);
}
----------------------------------------------------
/**
* 2.定义接口规范,被代理的基本接口
* 目标接口2
*/
public interface SayByeInterface {
public void sayBye(String str);
}
------------------------------------------------------
/**
* 3.接口的基本实现类,只实现了基础功能,被代理的基本对象
*目标对象
*/
public class InterfaceClass implements HelloWorldInterface , SayByeInterface{
@Override
public void sayHello(String str) {
System.out.println(str);
}
@Override
public void sayBye(String str) {
System.out.println(str + "......");
}
@Override
public String sayHello1(String str) {
System.out.println(str + "-------------");
return str;
}
}
---------------------------------------------------------------------
/**
* 4.代理处理器,进行被代理对象基本功能的丰富
*/
public class MyInvocationHandler implements InvocationHandler
{
//被代理的对象,目标对象
private Object target;
public MyInvocationHandler(Object target)
{
this.target = target;
}
/**
* 与代理基本类进行关联
* @proxy 被代理的基本类
* @method 被代理的方法
* @args 代理方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
if(method.getName().equals("sayBye"))
{
System.out.println("Good Bye--------");
obj = method.invoke(target, args);
System.out.println("Bye--------");
}
else
{
System.out.println("Hello world----------");
obj = method.invoke(target, args);
System.out.println("Hello--------");
}
return obj;
}
}
---------------------------------------------------------------
/**
* 5.测试主函数
*/
public class TsMain {
public static void main(String[] args) {
//被代理对象
InterfaceClass target = new InterfaceClass();
//代理处理器
MyInvocationHandler myHandler = new MyInvocationHandler(target);
//创建代理
//loader 接口实现类的类加载器
ClassLoader loader = InterfaceClass.class.getClassLoader();
//interfaces 被代理的接口
Class [] interfaces = new Class[]{ HelloWorldInterface.class ,SayByeInterface.class };
//得到代理
SayByeInterface service = (SayByeInterface)Proxy.newProxyInstance(loader, interfaces, myHandler);
//使用代理,调用被代理的方法
service.sayBye("tom");
//使用代理,调用被代理的方法
//多态强转
((HelloWorldInterface)service).sayHello("tom");
}
}
三、通过文本文件创建类对象
---------------------------------------------------
/**
* 测试通过文件创建类对象
*/
@Test
public void tsLoadClassByFile()
{
try {
InputStream is = ClassLoader.getSystemResourceAsStream("object.info");
Properties prop = new Properties();
prop.load(is);
String className = prop.getProperty("object.class");
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
String fieldName = prop.getProperty("object.prop1.name");
String fieldValue = prop.getProperty("object.prop1.value");
Field f = clazz.getDeclaredField(fieldName);
f.setAccessible(true);
if(f.getType() == String.class)
{
f.set(obj, fieldValue);
}
fieldName = prop.getProperty("object.prop2.name");
fieldValue = prop.getProperty("object.prop2.value");
f = clazz.getDeclaredField(fieldName);
f.setAccessible(true);
if(f.getType() == int.class)
{
f.set(obj, Integer.parseInt(fieldValue));
}
Person p = (Person)obj;
System.out.println(p.getAge());
is.close();
//System.out.println(className);
} catch (Exception e) {
e.printStackTrace();
}
}
四、NIO (New IO) : java.nio.Buffer
------------------------------------------------------
1.Buffer //缓冲区
【ByteBuffer】 //字节缓冲区,字节类的定长向量,是一个固定数据量的指定基本类型的数据容器
-- mark : 可以添加标记,位于position之前
-- position : 当前位置,类似于File的指针。位于limit之前,随着读写,自动更新
-- limit : 定义了可写数据的最后的空间(多少数据已经写入到文件中了)。小于capacity
-- capacity: 容量,ByteBuffer内部封装的字节数组的size
-- 0 <= mark <= position <= limit <= capacity
-- put():写入方法
-- get():读取方法
-- rewind(): 重绕 , pos = 0 ; mark丢弃
-- reset() : 重置, pos = mark;
-- flip():拍板,将当前的position设置成limit,并且将posion设置成0,丢弃mark
-- clear(): 清空,pos = 0 ; lim = capa ; mark = null
-- slice(): 切片,从当前缓冲区中划出前n个元素构造新的缓冲区,n表示当前缓冲区remaining大小。新,旧两个缓冲区操作同一个byte[],但是各自有各自的limit和pos
-- position():取出指针当前位置
-- position(int) : 设置指针到int位置
-- limit(): 取出当前指针最大可达到区域的值
-- limit(int ): 设置当前指针最大可达到的区域的值
五、ByteBuffer
-----------------------------------------------
1.创建ByteBuffer(堆中创建和离堆中创建)
-- ByteBuffer heapBF = ByteBuffer.allocate(1024 * 1024 * 100); //创建100M的字节缓冲区,在堆内存中
-- ByteBuffer offHeapBF = ByteBuffer.allocateDirect(1024 * 1024 * 100); //创建100M的字节缓冲区,在离堆内存中
2.获取ByteBuffer的容量capacity
-- bf.capacity();
/**
* 测试HeapByteBuffer
*/
@Test
public void tsHeapByteBuffer()
{
int size = 1024 * 1024 * 500;
ByteBuffer bf = ByteBuffer.allocate(size);
System.out.println(bf.capacity());
}
/**
* 测试OffHeapByteBuffer
*/
@Test
public void tsOffHeapByteBuffer()
{
int size = 1024 * 1024 * 500;
ByteBuffer bf = ByteBuffer.allocateDirect(size);
System.out.println(bf.capacity());
}
六、Channel
----------------------------------------------------
1.Channel是一个对象,可以通过它读取和写入数据
2.Channel是直接与缓冲区打交道的
3.Channel可以通过基本io流的getChannel()拿到
4.通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类), 而 通道 可以用于读、写或者同时用于读写。
5.使用堆缓冲和离堆缓冲,复制大文件,对比性能
/**
* 测试channel off Heap
*/
@Test
public void tsChannelOffHeap()
{
try {
long l = System.currentTimeMillis();
//输入流
FileInputStream fis = new FileInputStream("D:\\1.rar");
FileChannel srcFc = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream("D:\\2.rar");
FileChannel desFc = fos.getChannel();
//定义缓冲区
ByteBuffer dst = ByteBuffer.allocateDirect(1024 * 8);
//开始复制
int len = 0;
while((srcFc.read(dst)) != -1)
{
dst.flip();
desFc.write(dst);
dst.clear();
}
fis.close();
fos.close();
System.out.println("off heap time:" + (System.currentTimeMillis() - l));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 测试channel Heap
*/
@Test
public void tsChannelHeap()
{
try {
long l = System.currentTimeMillis();
//输入流
FileInputStream fis = new FileInputStream("D:\\1.rar");
FileChannel srcFc = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream("D:\\2.rar");
FileChannel desFc = fos.getChannel();
//定义缓冲区
ByteBuffer dst = ByteBuffer.allocate(1024 * 8);
//开始复制
int len = 0;
while((srcFc.read(dst)) != -1)
{
dst.flip();
desFc.write(dst);
dst.clear();
}
fis.close();
fos.close();
System.out.println("heap time:" + (System.currentTimeMillis() - l));
} catch (Exception e) {
e.printStackTrace();
}
}
七、GC 垃圾回收
------------------------------------------------
1.没有任何指针能够直接或者间接指向对象的时候,对象就具备了回收条件
/**
* 测试GC
*/
public void tsGC()
{
int size = 1024 * 1024 * 1024 * 1;
byte [] buf = new byte[size];
byte [] buf2 = buf;
buf = null;
System.gc(); //立刻进行垃圾回收
buf2 = null;
System.gc(); //立刻进行垃圾回收
}