1.克隆对象(深拷贝),复制对象,改原状态不会相互影响.
2.内部类:可访问外部类域,
3.代理(proxy) 实现任意接口的对象.
4.方法默认public,可定义常量(可认为没有实例域的抽象类)
实例类要声明public(默认包可见)
5.java是一种强类型的语言
6.实现Comparable接口可比较
要判断
if(getClass()!=o.getClass()){
throw new ClassCastException();
}
7.接口变量引用实现接口类对象
8.if(object instanceof Comparable) 判断实现接口
9.接口扩展 public interface Powered extends Moveable
10.double SPEED=55; ==( public static final) constrant(建议不书写多余关键字))
111.浅拷贝 除数字,基本类型外,其他引用
String类-不允许改变 --不同对象
Date可改变--有clone方法
数组.clone
11.Cloneable 只是作为标记(tagging interface),个人不建议这种写法
1)调用子对象的clone 可能修补深复制
2)Object有 protected Object clone()
子类调用重写 public Object clone();
j2se5 允许更改返回类型 public Employee clone();
3)深拷贝
public Employee clone() ..{
Employee o=(Employee)super.clone();
o.hireDated=(Date)hireDay.clone();
return o;
}
4)实现clone不会抛出异常,编译器不知道 要throws
是final类的话 可try..catch
12.子类只能扩展一个抽象类
13.序列化 安全,容易,低效
14.接口与回调callback
定时器调用对象方法
函数指针对应产物--method对象
//java.util.Timer 主要用于调度后台
public class TimerTest {
public static void main(String[] args) {
System.out.println("start....");
ActionListener listener=new TimePrinter();
Timer t=new Timer(1000, listener);
t.start();
JOptionPane.showMessageDialog(null, "Quit Program?");//对话框
System.exit(0);
}
}
class TimePrinter implements ActionListener{
/* (non-Javadoc)
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
System.out.println(new Date());
Toolkit.getDefaultToolkit().beep();//蜂鸣
}
}
15.内部类
a)访问外部类方法,域,这种引用在内部类不可见
类似于
public TimePrinter(Talking clock){
outer=clock;
}
编译器为内部类添加默认构造器(修改内部类构造器)
外部类的实例方法自动添加this
ActionListener l=new TimePrinter(this);
明确指定内部类
ActionListener l=this.new TimePrinter();
编译器翻译为new TalkingClock$TimePrinter(this,null);
引用外部类.beep
if(TalkClock.this.beep) ...
内部类访问了外部域 会创建static access$0(outer) 方法获得外部域
b)对包中其他类隐藏
c)回调函数经常用anonymous
1)内部域只能被外围方法访问
2)内部类有指向外部实例的引用8
3)内部类实例由外部类构造才有
16.只有内部类可为私有,一般为包可见,public
166. 可在方法中定义局部类(在局部用到)(不能定义public private,被默认定义为块中可见)
17.内部类是一个编译器现象$间隔,与虚拟机无关
一种实例方法new TimerTest().new TimePrinter();
18.内部类访问方法局部变量(声明final)--传入参数被保存到局部变量
有时不只是局部用数组方式可保存值 final int[] counter=new int[1];
19.final被赋值一次,可不初始化
20.匿名内部类 方法不可引用,直接赋值给变量
ActionListener listener=new ActionListener(){//使用接口名或超类名
public void actionPerformed(..){
.......
}
}
21.匿名内部类没类名,没构造器,可提供给超类构造器
22.静态内部类,不能引用外部类(有的用nested class)
内部公有类访问 ArrayLog.Pair
public static class Pair..
23.代理 运行时创建实现一组接口的类(编译时无法确定接口使用)
一种不好的方式 生成结果类,与编译器放一起,加载
代理:
1)实现指定接口全部方法
2)object的toString equals..hashCode()全部方法
不在运行时定义这些方法新代码,提供调用处理器,实现invokeHandler接口,
invoke方法调用代理对象方法
Proxy类的newProxyInstance
null表身默认类加载器
Class[] 每个元素都是要实现的接口
调用处理器
使用情况
a)路由对远程服务方法调用
b)运行期,由用户接口事件和动作关联
c)调试
public class TraceHandler implements InvocationHandler {
private Object target;
/**
*
*/
public TraceHandler(Object t) {
target=t;
}
/* (non-Javadoc)
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print(target);
System.out.print("."+method.getName()+"(");
if(args!=null){
for(int i=0;i<args.length;i++){
System.out.print(args[i]);
if(i<args.length-1)
System.out.print(",");
}
System.out.println(")");
}
return method.invoke(target, args);//只是调用,并不覆盖
}
public static void main(String[] args) {
Object[] elements=new Object[1000];
for(int i=0;i<elements.length;i++){
Integer value=i+1;
InvocationHandler handler=new TraceHandler(value);//代理类
Class[] interfaces=new Class[]{Comparable.class};//接口
elements[i]=Proxy.newProxyInstance(null, interfaces, handler);//代理对象
}
Integer key=new Random().nextInt(elements.length)+1;
int result=Arrays.binarySearch(elements, key);
if(result>=0)
System.out.println(elements[result]);
}
}
24.代理类运行时创建,创建后是常规类
a)调用处理器--继承类(代理类只能有一个实例域)
b)代理类未定义类名的生成$Proxy开头类 Proxy.newProxyInstance..
c)特定类加载器,预设接口,只能有一个代理类 ,如上的到的是2/多个实例
d)一定是public final ,所有接口都public,既不属于特定包,否则接口,代理类要在同一包
Proxy.getProxyClass Proxy.isProxyClass