大家好,前几天给大家写了一篇“java,Android面试必问的JAVA基础部分(点击访问)”,现在给出的是JAVA高级部分,如果你们能拿够掌握这两部分,那么在面试的过程中你们就会游刃有余了,后续还会给大家写出Android基础/高级部分”,希望能帮助有需要的朋友.
对反射的理解
1.获取java反射类的字节码文件
2.获取的方法有三种
1.Class.forName(类名)
2.类名.getClass
3.this.class
3.通过获取到的字节码,就能获取到其中的方法(methode),属性变量(File),构造函数(Coustructor)
代码
public class Invoke {
public static void main(String[] args) throws Exception {
invoke();
invoke2();
invoke3();
invoke4();
}
//步骤过程:获取字节码->获取方法->方法请求.invoke
private static void invoke() throws Exception {
ArrayList list = new ArrayList();
// 1.class
Class clazz = list.getClass();
// 2.method //3.obj
Method method = clazz.getMethod("add", Object.class);
// 4.invoke
method.invoke(list, 132);
method.invoke(list, "aa");
method.invoke(list, false);
System.out.println(list);
//输出
//[132, aa, false]
}
//一句话一气呵成写法
private static void invoke2() throws Exception {
ArrayList list = new ArrayList();
list.getClass().getMethod("add", Object.class).invoke(list, "good job");
System.out.println(list);
//输出
} //[goodjob, aa, false]
/**
* ͨ注意:需要类名的全称,否则无效
* Class.forName("java.util.ArrayList")
* Class.forName("ArrayList")这样虚拟机识别不到该类
*/
private static void invoke3() throws Exception {
// Class> arrayList = Class.forName("ArrayList");
Class> arrayList = Class.forName("java.util.ArrayList");
//getDeclaredMethods,获取:公共、保护、默认(包)访问和私有方法,但不包括继承的方法
Method[] declaredMethods = arrayList.getDeclaredMethods();
for (Method m : declaredMethods) {
System.out.println(m);
}
}
/**
* 获取属性变量
*/
private static void invoke4() throws Exception {
Class> moon = Class.forName("com.javabase.Moon"); //填写完整类名
Field[] fields = moon.getDeclaredFields();
for (Field file :
fields) {
System.out.println("-------------"+file);
}
//输出:
//-------------private int com.example.Moon.age
//-------------private java.lang.String com.example.Moon.name
//-------------private long com.example.Moon.size
//-------------public int com.example.Moon.num
//获取
Method[] declaredMethods = moon.getDeclaredMethods();
for (Method m :
declaredMethods) {
System.out.println(m);
//输出:
//public java.lang.String com.example.Moon.toString()
//private java.lang.String com.example.Moon.getName()
//protected long com.example.Moon.getSize()
//public int com.example.Moon.getAge()
}
}
}
包下的类:
class Moon {
private int age;
private String name;
private long size;
public int num;
public int getAge() {
return age;
}
private String getName() {
return name;
}
protected long getSize() {
return size;
}
@Override
public String toString() {
return "Moon{" + "age=" + age + ", name='" + name + '\'' + ", size=" + size + '}';
}
}
静态代理 | 动态代理 |
---|---|
只代理一个类 | 代理一个接口下的多个实现类 |
知道代理的是什么 | 不知道代理什么,运行的时候才知道 |
笔试题:
写一个arrayList的动态代理类:
/**
* 动态代理实例
*/
public class Invoke_Dynamic {
public static void main(String[] args) {
dynimac();
}
/**
* 1.创建一个需求的对象 list
* 2.通过:代理Proxy.new获取代理实例,得到动态代理对象.
* 3.内部参数:
* 1.反射类.获取载入器 loder
* 2.反射类.获取接口
* 3.创建"请求处理"接口实例对象,并重写invoke方法
* 返回:方法对象.使用
*/
private static void dynimac() {
final List list = new ArrayList<>(); //1.目标对象
List proxy = (List) Proxy.newProxyInstance( //2.代理.新的代理实例 返回的是集合
list.getClass().getClassLoader()//3.反射类.载入器
, list.getClass().getInterfaces()//4.反射类.获取接口
, new InvocationHandler() {//创建"请求处理"接口实例
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(list, args);//返回:方法.请求(目标多少,数组对象)
}
});
proxy.add(123);
proxy.add("你好");
proxy.add(true);
System.out.println(proxy);
}
}
输出结果:
[123, 你好, true]
分为三大类:
1.”创建”型模式(5)
工厂方法,抽象工厂,单例,建造者,原型
适配器,装饰,代理,外观,桥接,组合,享元
策略,模板方法,观察者,迭代子,责任链,命令,备忘录
为了方便大家的复习和掌握,我特意针对每一种设计模式写了他们对应的一篇介绍,大家可以点击他们各自的连接进行详细的学习:
(点我进入”工厂方法模式”板块的学习)
(点我进入”抽象方法模式”板块的学习)
(点我进入”单例模式”板块的学习)
(点我进入”建造者模式”板块的学习)
(点我进入”适配器模式”板块的学习)
(点我进入”装饰模式”板块的学习)
(点我进入”策略模式”板块的学习)
(点我进入”观察者模式”板块的学习)
垃圾回收机制GC(Garbage COllector):
垃圾为什么能回收,肯定经过了发现垃圾的过程再到回收的过程,所以可以说分成两个阶段:搜索和回收阶段.
搜索算法:
1.”引用”“计数器”算法(JDK1.1后不用了)
1.给"每个对象"设定一个计算器,当被引用时+1,引用失效时-1,为0时,Jvm认为不再被使用,成为了"垃圾".
2.使用简单,效率高,但是不能解决"循环引用(A引用B,B引用A,AB不被其他对象引用,那么就会累加,所以不符合)"的问题,而且每次都增加和删除开销太大,所以废弃了.
2.”根”搜索算法
1.通过根名为”GC Roots”的对象作为起点,往下搜索
2.搜索到对象,那么和对象之间的”路径”成为引用链(Reference Chain)
3.如果那些垂线到GC Roots”没有”引用链,那么该对象就是不可用对象,可回收
可作为垃圾回收机根的 对象:
1."虚拟机栈"中引用的;
2.方法区中"静态属性"引用的;
3.方法区中"常量"引用的
回收算法:
1.标记-清除算法
两个阶段:1.标记;2.清除
1.标记阶段:标记所要回收的对象
2.清除阶段紧随其后,删除不可用的标记对象
是基础的收集算法,单效率不高,易产生大量不连续空间,当程序需要分配大内存时.可能无法找到足够的连续空间(大的需要连续的)
2.复制算法
1.把内存分成等半两边,每次只用一边
2.垃圾回收时,存活的放另一边,剩下的就是被清理的一块.
效率高.但是每次只能一办内存,所以内存利用率不高
3.标记-整理算法
在标记-清除算法上升级:
1.不是逐个删除
2.而是吧存活的放入内存一端,然后回收"边界以为"的内存
4.分代收集
根据对象”存活时间”分为两种:新生代,老年代
1.新生代:
用复制算法.
2.老年代:
用标记整理算法.
分为3部分:
1.方法区(Method Area)
常数池,命名的常量,String常量,Static变量都保持在方法区.
2.JAVA”栈”
java stack 后进先出的特点,一个栈的空间可能是连续也可能不连续
最典型用法就是方法的调用:虚拟机每调用一次方法就创建一个”方法帧”(frame),退出(完成)方法的时候就”弹出-pop”这个帧.
3.JAVA”堆”
java head 顺序是随意不确定性的.
二.JAVA内存的分配
1.基础数据类型(字符串不是基础,在data区)-直接在”栈”空间分配;
2.方法的”形式参数”,直接在栈,用完从栈回收
3.方法的”引用参数”,在栈分配地址,比指向堆空间对象区,方法调用完用完从栈回收.
4.引用数据类型(new XXX),栈是地址,堆是类对象具体的
5.局部变量new的,栈堆都分配,声明周期结束,栈立即回收,堆的等回收机制
6.方法调用时的”实际参数”,在栈,用完后从栈释放
7.字符串常量:在data区分配;this在堆(this就是对象)
8.数组:栈分配”数组名”,堆分配实际大小
(这个是相当重要的,请大家好好理解)
分为四类,从小到大分别为:强->软->弱->虚,很好记.
1.强引用:
天天敲代码 new的对象就是强引用,当"强引用"对象还使用着,那么垃圾回收器不会"回收"它,即使内存不够的时候,你可抛出内存溢出(OutofMemory)使程序终止,也不回收"强引用"对象
java的对象是位于堆head中,堆中的对象有:”强可及”对象,”软可及”对象,弱可及,虚可及,不可及.对象到底属于哪种可及由最强引用决定.
String abc=new String("abc"); //1
SoftReference<String> softRef=new SoftReference<String>(abc); //2 WeakReference<String> weakRef = new WeakReference<String>(abc); //3 abc=null; //4
softRef.clear();//5
第一行,建立abc到该对象的强引用,对象是强可及
第二行,第三行,被分别创建”堆对象”的软,和弱引用,此时”abc对象”已经有了3个引用,此时abc仍是强可及
第四行 abc = null;堆中对象不再是强可及的,变成了软可及
第五行后变成弱可及的了.
* 2.软引用:
1.如果对象只有"软引用",那么如果内存空间还足够,就不会回收它,如果不足,就回收,这是和强不同的第一点
2.配合引用队列ReferenceQueue使用,如果如果软引用对象被回收了,虚拟机会把该软件放入引用队列.
3.弱引用:
1.弱引用,可有可无,被垃圾回收器扫描到:随时把它干掉
2.和软引用的区别:比弱引用更低的生命周期,一般发现弱引用,不断内存是否充足都会干掉
3.也需要一个引用对列RefereneQueue配合,同样一被回收,也会被虚拟机放入引用对列
4.虚引用:
1.形同虚设,不会决定对象的生命周期,如果只持有虚引用,那么如同没有,任何时候都可能被回收,主要用于"跟踪对象被垃圾回收的活动"
2.也要和引用队列联合使用.当发现垃圾回收器准备回收一个对象,当发现"对象"还有虚引用,就会在回收对象之前,把这个虚引用加入到与之无关联的引用队列
3.通过判断引用队列中是否加入了虚引用,来了解"被引用的对象"是否要被垃圾回收.
4.如果某个虚引用已经被加入到队列,那么就可以在所引用的对象在"被回收之前"采取必要行动.
1.”根”类加载器
Bottstrap:C++写的,看不到源码
2.”扩展”类加载器
Extension:加载位置:jre\lib\ext
3.”系统(应用)”类加载器
System/App:加载位置:classpath中
4.”自定义”加载器
必须继承ClassLoader
类初始化步骤: