14.通过反射取得并修改数组的信息:
import java.lang.reflect.*;
class hello{
public static void main(String[] args) {
int[] temp={1,2,3,4,5};
Class
demo=temp.getClass().getComponentType();
System.out.println("数组类型: "+demo.getName());
System.out.println("数组长度 "+Array.getLength(temp));
System.out.println("数组的第一个元素: "+Array.get(temp, 0));
Array.set(temp, 0, 100);
System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0));
}
}
输出:
数组类型: int
数组长度 5
数组的第一个元素: 1
修改之后数组第一个元素为: 100
15.通过反射修改数组大小:class hello{
public static void main(String[] args) {
int[] temp={1,2,3,4,5,6,7,8,9};
int[] newTemp=(int[])arrayInc(temp,15);
print(newTemp);
System.out.println("=====================");
String[] atr={"a","b","c"};
String[] str1=(String[])arrayInc(atr,8);
print(str1);
}
/**
* 修改数组大小
* */
public static Object arrayInc(Object obj,int len){
Class
arr=obj.getClass().getComponentType();
Object newArr=Array.newInstance(arr, len);
int co=Array.getLength(obj);
System.arraycopy(obj, 0, newArr, 0, co);
return newArr;
}
/**
* 打印
* */
public static void print(Object obj){
Class
c=obj.getClass();
if(!c.isArray()){
return;
}
System.out.println("数组长度为: "+Array.getLength(obj));
for (int i = 0; i < Array.getLength(obj); i++) {
System.out.print(Array.get(obj, i)+" ");
}
}
}输出:
数组长度为: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================
数组长度为: 8
a b c null null null null null
动态代理:
首先来看看如何获得类加载器:
class test{
}
class hello{
public static void main(String[] args) {
test t=new test();
System.out.println("类加载器 "+t.getClass().getClassLoader().getClass().getName());
}
}
输出:类加载器 sun.misc.Launcher$AppClassLoader;
其实在java中有三种类类加载器。
1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,以完成代理的具体操作。
package Reflect;
import java.lang.reflect.*;
//定义项目接口
interface Subject {
public String say(String name, int age);
}
// 定义真实项目
class RealSubject implements Subject {
@Override
public String say(String name, int age) {
return name + " " + age;
}
}
class MyInvocationHandler implements InvocationHandler {
private Object obj = null;
public Object bind(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object temp = method.invoke(this.obj, args);
return temp;
}
}
class hello {
public static void main(String[] args) {
MyInvocationHandler demo = new MyInvocationHandler();
Subject sub = (Subject) demo.bind(new RealSubject());
String info = sub.say("Rollen", 20);
System.out.println(info);
}
}
输出:Rollen 20;
类的生命周期
在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。
类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。但是同一个类只会被类装载器装载以前
链接就是把二进制数据组装为可以运行的状态。
链接分为校验,准备,解析这3个阶段
校验一般用来确认此二进制文件是否适合当前的JVM(版本),
准备就是为静态成员分配内存空间,。并设置默认值
解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)
完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。
当没有任何引用指向Class对象时就会被