`
lvwenwen
  • 浏览: 956075 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

java基础加强笔记

阅读更多
----------------------------------------------------------传智播客基础加强知识点----------------------------------------------------------
注意:1.关注黑马训练营(http://edu.csdn.net/heima/),黑马论坛(http://bbs.itheima.com/forum-16-1.html),学习核心技术
(1).课程大纲
1.eclipse的使用技巧
2.静态导入
3.可变参数与for循环增强
4.基本数据类型的自动拆箱与装箱
5.枚举
6.反射
7.JavaBean内省
8.beanutils工具包
9.注解
10.泛型
11.类加载器
12.代理(动态代理)
13.线程并发库(线程)

1.java ee
ide  itegrity development environment (集成开发环境)
jms
jmx
jndi
享元模式 flyweight() 有很多个小的对象,他们有很多属性相同,把他们变成一个对象,不同的属性把他们变成方法的参数,称之为外部状态,相同的属性称之为内部状态
1.eclipse 的使用技巧
2.可变参数(1.必须放在最后,用...
3.基本数据类型的自动拆箱与装箱
1.java ee
ide  itegrity development environment (集成开发环境)
jms
jmx
jndi

享元模式 flyweight() 有很多个小的对象,他们有很多属性相同,把他们变成一个对象,不同的属性把他们变成方法的参数,称之为外部状态,相同的属性称之为内部状态
1.1
枚举:其实就是一个对象,只能指定特定的值,枚举相当于一个类

内部类:

public final static WeekDay1 SUN = new WeekDay1() {

public WeekDay1 nextDay() {
return MON;
}

};
public final static WeekDay1 MON = new WeekDay1() {

public WeekDay1 nextDay() {
return SUN;
}

};

public abstract WeekDay1 nextDay();

/*
* public WeekDay nextDay(){ if(this == SUN){ return MON; }else{ return SUN;
* } }
*/

public String toString() {
return this == SUN ? "SUN" : "MON";
}
public enum TrafficLamp{
RED(30){
public  TrafficLamp nextLamp(){
return GREEN;
}
},
GREEN(45){
public  TrafficLamp nextLamp(){
return YELLOW;
}
},
YELLOW(5){
public  TrafficLamp nextLamp(){
return RED;
}
};
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){this.time = time;}

Class cls1 =Date.class字节码1;
Class cls2 =Person.class字节码2;

Person p1= new Person();
person p2 =new Person();
//得到字节码的方式
System.class;
p1.getClass(); //获取字节码
Class.forName("java.lang.String"); Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
//返回字节码,如果之前编译过就直接取,类加载器加载

反射:就是把java类的各种成分映射成java类

Constructor constructor1 =String.class.getConstructor();
constructor1.newInstance();

1.内部类可以添加四个访问修饰符,外部类只能有两个修饰符(public,默认修饰呼)
2.类的方法返回的类型可以是自己的类型,类里面可以定义静态常量,常量指向的结果就是自己这个类型的实际对象
3.最复杂的枚举(类部类)
public enum TrafficLamp{
RED(30){
public TrafficLamp nextLamp() {
return GREEN;
}

},
GREEN(45){
public TrafficLamp nextLamp() {
return YELLOW;
}

},
YELLOW(5){
public TrafficLamp nextLamp() {
return RED;
}};

public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp (int time){this.time=time;}
}

4.枚举只有一个成员时,就可以作为一种单例的实现方式。枚举搞出的对象永远是那么一个,枚举就是一个特殊的类,(构造方法不用写,new instance()自动生成)
5.枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。


1.2 反射(structs,hibernate,spring,junit 用到反射)
反射的定义:反射就是把Java类中的各种成分映射成相应的java类
1.基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Person p1=new Person();
Person p2=new Person();

Class cls1=字节码1;
class cls2=字节码2;
class 的是实列对象代表类存里面的字节码
把类的字节码加载到内存中间来,
字节码:当我们在程序中用到类时,首先要把类编译成字节码放到硬盘上(变成二进制代码),要把二进制代码加载到内存里面来,接着才可以用他创建一个个对象
2.class。forname("com.java.string")的作用是返回字节码,返回方式有两种,第一,这份字节码曾经被加载过,已经呆在java虚灵机里面 ,直接返回,
第二,java虚灵机没有这份字节码,就用类加载器加载(classLoader()),并放到内存里面
3.创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));
//调用获得的方法时要用到上面相同类型的实例对象

class -->constructor--->new object
对字节码的比较,用==比较

1.spirng 就是利用反射实现,你在配置文件写了某些东西,利用反射扫描你的文件,然后把你的文件某些东西改掉
2.理解反射:

public class ReflectPoint {
private Date birthday = new Date();

private int x;
public int y;
public String str1 = "bball";
public String str2 = "bbasketball";
public String str3 = "itcabbst";

public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}


@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}


@Override
public String toString(){
return str1 + ":" + str2 + ":" + str3;
}


public int getX() {
return x;
}


public void setX(int x) {
this.x = x;
}


public int getY() {
return y;
}


public void setY(int y) {
this.y = y;
}


public Date getBirthday() {
return birthday;
}


public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}

private static void changeStringValue(Object obj) throws Exception {
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
//if(field.getType().equals(String.class)){
if(field.getType() == String.class){
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}

}

ReflectPoint pt1 = new ReflectPoint(3,5);
changeStringValue(pt1);
System.out.println(pt1);
1.静态方法调用时,不需要对象
2.反射调用main方法
        String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
//mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
equals 比较hashcode的值,覆盖equals方法
Hashset,treeSet 不允许重复,如果重复就放不进,而ArrayList里面的值是有序的,可以重复
如果一个对象equals 相等,则应有相同的hashcode(只要求实现hashcode的算法,如treeset,hashset,而arraylist不用),
hashcode 的作用:
内存泄漏:比如定义一个变量,后面程序没用他,而他占用内存,一直没有释放

getRealPath();//得到项目真实路径
getResource();

javaBean :生成get ,set 方法, gettime--->time,getCPU ---->CPU

快捷键:alt+shirt+s

内省:对javaBean 生成get,set方法

2.BeanUtils 的用法:
BeanUtils.getProperty,BeanUtils.setProperty(pt1,"x","9");

1.2:注解,一个注解就是一个类
注解的作用:相当于一种标记,标记可以加在包,类,字段(成员变量),局部变量,方法,方法的参数
2.反射要先获取字节码,javac把源文件编译成字节码可能去掉注解,类加载器把class文件调到内存里来可能去掉注解
        3.反射获取注解(先获取字节码):if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);

2.泛型是给编译器看的,运行时就不管用了,
参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>(); //错误!///不写<Object>没错,写了就是明知故犯
Vector<Object> v = new Vector<String>(); //也错误!
   
    3.泛型:使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
public static void printCollection(Collection<Object> cols) {
for(Object obj:cols) {
System.out.println(obj);
}
/* cols.add("string");//没错
cols = new HashSet<Date>();//会报告错误!*/

public static void printCollection(Collection<?> cols) {
for(Object obj:cols) {
System.out.println(obj);
}
//cols.add("string");//错误,因为它不知自己未来匹配就一定是String
cols.size();//没错,此方法与类型参数没有关系
cols = new HashSet<Date>();
}

泛型:只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,5);语句会报告编译错误。
1.类加载器,java虚拟机中可以安装多个内加载器,系统默认有三个主要类加载器,类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。
系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader
类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。


类加载器与委托机制(儿子委托父亲,父亲委托给爷爷,即委托给上级)每个类加载器加载类时,又先委托给其上级类加载器。

1.模板方法设计模式:父类->loadClass ,写类加载器的原来,即用到此设计模式

子类1(自己干)
子类2(自己干)

2.编译错误与运行错误的区别:1.编译错误一般是语法错误,用javac *.java通不过,如:比如包名或内部类名写错等等
,运行错误包括逻辑错误如:一般是逻辑上的问题,如数组超界、空指针、……等。
,其它如资源耗尽(内存用完等),URL错误(输入错误的链接地址)等. 即逻辑错误等


3.代理的概念与作用:
类图,代理原理,工厂模式

面向方面的编程 (Aspect oriented rogram ,简称 AOP)
使用代理技术正好可以解决这种问题,代理是实现AOP功能的核心和关键技术,只要是面向方面的编程就要涉及到代理
单线程:StringBUilder ,多线程:StringBuffer效率高,线程安全

匿名内部类
Proxy 代理api
代理就是把目标加进来,传进去就是一个对象的形式

Spring 就是这个动态代理 实现的,spring (target ,advice 两个参数)
方法里面的内部类要访问局部变量,变量必须加final

spring 两大原理, beanFactory ,Aop ,代理
(1.1)
枚举:其实就是一个对象,只能指定特定的值,枚举相当于一个类
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个
如果想在一个类中编写完各个枚举类和测试调用类,那么可以将枚举类定义成调用类的内部类。
总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.getClass().getName和WeekDay.class.getName()。

内部类(匿名):
public final static WeekDay1 SUN = new WeekDay1() {
public WeekDay1 nextDay() {
return MON;
}

};
public final static WeekDay1 MON = new WeekDay1() {

public WeekDay1 nextDay() {
return SUN;
}

};

public abstract WeekDay1 nextDay();

/*
* public WeekDay nextDay(){ if(this == SUN){ return MON; }else{ return SUN;
* } }
*/

public String toString() {
return this == SUN ? "SUN" : "MON";
}
public enum TrafficLamp{
RED(30){
public  TrafficLamp nextLamp(){
return GREEN;
}
},
GREEN(45){
public  TrafficLamp nextLamp(){
return YELLOW;
}
},
YELLOW(5){
public  TrafficLamp nextLamp(){
return RED;
}
};
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){this.time = time;}

Class cls1 =Date.class字节码1;
Class cls2 =Person.class字节码2;

Person p1= new Person();
person p2 =new Person();
//得到字节码的方式
System.class;
p1.getClass(); //获取字节码
Class.forName("java.lang.String"); Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
//返回字节码,如果之前编译过就直接取,类加载器加载

反射:就是把java类的各种成分映射成java类

Constructor constructor1 =String.class.getConstructor();
constructor1.newInstance();

1.内部类可以添加四个访问修饰符,外部类只能有两个修饰符(public,默认修饰呼)
2.类的方法返回的类型可以是自己的类型,类里面可以定义静态常量,常量指向的结果就是自己这个类型的实际对象
3.最复杂的枚举(类部类)
public enum TrafficLamp{
RED(30){
public TrafficLamp nextLamp() {
return GREEN;
}

},
GREEN(45){
public TrafficLamp nextLamp() {
return YELLOW;
}

},
YELLOW(5){
public TrafficLamp nextLamp() {
return RED;
}};

public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp (int time){this.time=time;}
}

4.枚举只有一个成员时,就可以作为一种单例的实现方式。枚举搞出的对象永远是那么一个,枚举就是一个特殊的类,(构造方法不用写,new instance()自动生成)
5.枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
6.带构造方法的枚举
构造方法必须定义成私有的
枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
7.枚举只有一个成员时,就可以作为一种单例的实现方式。

(1.2) 反射(structs,hibernate,spring,junit 用到反射)
反射的定义:反射就是把Java类中的各种成分映射成相应的java类,反射的基石 Class类
1.基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Person p1=new Person();
Person p2=new Person();
Class cls1=字节码1;
class cls2=字节码2;
class 的是实列对象代表类存里面的字节码
把类的字节码加载到内存中间来,
字节码:当我们在程序中用到类时,首先要把类编译成字节码放到硬盘上(变成二进制代码),要把二进制代码加载到内存里面来,接着才可以用他创建一个个对象
如何得到各个字节码对应的实例对象( Class类型)
类名.class,例如,System.class
对象.getClass(),例如,new Date().getClass()
Class.forName("类名"),例如,Class.forName("java.util.Date");
字节码只被装载一次,字节码只被装载一次,静态代码块不是在类加载时被调用的,而是第一个实例对象被创建时才执行的。
2.class。forname("com.java.string")的作用是返回字节码,返回方式有两种,第一,这份字节码曾经被加载过,已经呆在java虚灵机里面 ,直接返回,
第二,java虚灵机没有这份字节码,就用类加载器加载(classLoader()),并放到内存里面
3.创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));
//调用获得的方法时要用到上面相同类型的实例对象
class -->constructor--->new object
对字节码的比较,用==比较
1.spirng 就是利用反射实现,你在配置文件写了某些东西,利用反射扫描你的文件,然后把你的文件某些东西改掉
2.理解反射:
public class ReflectPoint {
private Date birthday = new Date();

private int x;
public int y;
public String str1 = "bball";
public String str2 = "bbasketball";
public String str3 = "itcabbst";

public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}


@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}


@Override
public String toString(){
return str1 + ":" + str2 + ":" + str3;
}


public int getX() {
return x;
}


public void setX(int x) {
this.x = x;
}


public int getY() {
return y;
}


public void setY(int y) {
this.y = y;
}


public Date getBirthday() {
return birthday;
}


public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
//用反射改变值(写出这个方法,就懂反射)
private static void changeStringValue(Object obj) throws Exception {
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
//if(field.getType().equals(String.class)){
if(field.getType() == String.class){
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}

}
ReflectPoint pt1 = new ReflectPoint(3,5);
changeStringValue(pt1);
System.out.println(pt1);
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
ReflectPoint pt=new ReflectPoint(3,5);
Field fieldYe =pt.getClass().getField("y");
fieldYe.get(pt);
//fieldY的值是多少?是5,错!fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
1.静态方法调用时,不需要对象
2.反射调用main方法,反射的作用===>实现框架功能
        String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
//mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
equals 比较hashcode的值,覆盖equals方法
Hashset,treeSet 不允许重复,如果重复就放不进,而ArrayList里面的值是有序的,可以重复
如果一个对象equals 相等,则应有相同的hashcode,拥有相同的hashcode 但它的方法不一定相同
java.lang.Object中对hashCode的约定:
   1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。
   2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。
   3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。
   4.当equals方法被重写时,通常有必要重写   hashCode   方法,以维护   hashCode   方法的常规协定
   5.有一个概念要牢记,两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象。
   6.重写了equals(),为什么还要重写hashCode()呢?
   想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊
   7.hashcode的作用:hashcode是用来查找的
(只要求实现hashcode的算法,如treeset,hashset,而arraylist不用),
hashcode 的作用:
内存泄漏:比如定义一个变量,后面程序没用他,而他占用内存,一直没有释放
getRealPath();//得到项目真实路径
getResource();
1.解决后台乱码问题: new String(StringName.getBytes("ISO8859-1","GBK")); 此类问题在浏览器直接传参数时会发生(不是经过页面传值)
javaBean :生成get ,set 方法, gettime--->time,getCPU ---->CPU

快捷键:alt+shirt+s

4.内省:对javaBean 生成get,set方法
?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
setId()的属性名?id
isLast()的属性名?last
setCPU的属性名是什么??CPU
getUPS的属性名是什么??UPS
2.BeanUtils 的用法:
BeanUtils.getProperty,BeanUtils.setProperty(pt1,"x","9");
(1.3):注解,一个注解就是一个类,枚举和注解都是特殊的类
注解的作用:相当于一种标记,标记可以加在包,类,字段(成员变量),局部变量,方法,方法的参数
2.反射要先获取字节码,javac把源文件编译成字节码可能去掉注解,类加载器把class文件调到内存里来可能去掉注解
        3.反射获取注解(先获取字节码):if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);

(1.4)泛型:泛型是给编译器看的,运行时就不管用了,
参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>(); //错误!///不写<Object>没错,写了就是明知故犯
Vector<Object> v = new Vector<String>(); //也错误!
  3.泛型:使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
   public static void printCollection(Collection<Object> cols) {
for(Object obj:cols) {
System.out.println(obj);
}
/* cols.add("string");//没错
cols = new HashSet<Date>();//会报告错误!*/

public static void printCollection(Collection<?> cols) {
for(Object obj:cols) {
System.out.println(obj);
}
//cols.add("string");//错误,因为它不知自己未来匹配就一定是String
cols.size();//没错,此方法与类型参数没有关系
cols = new HashSet<Date>();
}

泛型:只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,5);语句会报告编译错误。
(1.5).类加载器,java虚拟机中可以安装多个内加载器,系统默认有三个主要类加载器,类加载器也是Java类,
因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。
说明放置在不同位置的类确实由不同的类加载器加载的
系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader
类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。
类加载器与委托机制(儿子委托父亲,父亲委托给爷爷,即委托给上级,但不能给下级(因为没有getChild()方法,有也不能确定哪一个))每个类加载器加载类时,又先委托给其上级类加载器。
1.模板方法设计模式:父类->loadClass ,写类加载器的原来,即用到此设计模式
子类1(自己干)
子类2(自己干)

2.编译错误与运行错误的区别:1.编译错误一般是语法错误,用javac *.java通不过,如:比如包名或内部类名写错等等
,运行错误包括逻辑错误如:一般是逻辑上的问题,如数组超界、空指针、……等。
,其它如资源耗尽(内存用完等),URL错误(输入错误的链接地址)等. 即逻辑错误等


3.代理的概念与作用:
类图,代理原理,工厂模式
代理模式:
代理模式涉及的角色:
1:抽象主题角色.声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替.
2:代理主题角色.含有真实主题的引用,从而可以在任何时候操作真实主题,代理主题功过提供和真实主题相同的接口,使它可以随时代替真实主题.代理主题通过持有真实主题的引用,不但可以控制真实主题的创建或删除,可以在真实主题被调用前进行拦截,或在调用后进行某些操作.
3:真实代理对象.定义了代理角色所代表的具体对象.
动态代理:
面向方面的编程 (Aspect oriented program ,简称 AOP),代理是实现AOP功能的核心和关键技术,Aop用到代理,Spring 用反射实现;
使用代理技术正好可以解决这种问题,代理是实现AOP功能的核心和关键技术,只要是面向方面的编程就要涉及到代理
单线程:StringBUilder ,多线程:StringBuffer效率高,线程安全
1.内部类的方法要访问局部变量,局部变量前要加final

动态代理(核心理解):1.把目标抽取成参数(traget),把系统功能的方法抽取成对象
(advice,可理解为参数)
动态代理的原理:客户端调用代理,代理的构造方法接受一个Handler(把
Handler对象传给代理的构造方法,
然后代理的其他方法去找刚才传进来的那个handler的invoke()方法,
handler的invoke()方法可以加入日志功能(比如:权限判断(做具体的一件
事等),),),还可以去调用目标,调用目标的哪个方法(根据Metod去找目标的
方法))
然后客户端调用代理的各个方法,代理的各个方法会把请求转发给刚才通过
方法传进去的
那个handler对象,这个handler对象又把各个请求分发给目标的相信方法
就是到底加入什么样的系统功能,我可以在程序运行中来临时的设值,而不
是在编码的时候硬邦邦的指定好
面向切面编程:把日志功能,系统功能封装成一个对象,
就是把切面的代码,用对象的方式进行封装,然后以对象的形式传递给你,
你执行对象就等于执行了切面的代码
java主要是通过Proxy类和InvocationHandler接口来给实现对代理模式的支持的.
动态代理实现的源码:
1.接口
public interface Advice {
void beforeMethod(Method method);
void afterMethod(Method method);
}
2.实现类
public class MyAdvice implements Advice {
long beginTime = 0;
public void afterMethod(Method method) {
// TODO Auto-generated method stub
System.out.println("从传智播客毕业上班啦!");
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of " + (endTime - beginTime));
}

public void beforeMethod(Method method) {
// TODO Auto-generated method stub
System.out.println("到传智播客来学习啦!");
beginTime = System.currentTimeMillis();
}
}
3.写动态代理类
//把目标抽取成参数
private static Object getProxy(final Object target,final Advice advice) {
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
/*new Class[]{Collection.class},*/
target.getClass().getInterfaces(),
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/*long beginTime = System.currentTimeMillis();
Object retVal = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of " + (endTime - beginTime));
return retVal;*/
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
}
);
return proxy3;
}
测试类:
final ArrayList target = new ArrayList();
Collection proxy3 = (Collection)getProxy(target,new MyAdvice());
proxy3.add("zxx");
proxy3.add("lhm");
proxy3.add("bxd");
System.out.println(proxy3.size());
System.out.println(proxy3.getClass().getName());

装饰设计模式:动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
装饰者模式:装饰是构造函数参数传递进行增强 (与继承的最大区别)
1. 装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者模式比继承提供了更有弹性的替代方案。装饰模式比继承要灵活。避免了继承体系臃肿。
而且降低了类于类之间的关系。
2.装饰者模式在JDK中的代表
java.io包:
InputStream---抽象组件
FileInputStream, StringBufferInputStream,ByteArrayInputStream.FilterInputStream---这些类继承于 InputStream类,是可以被装饰者包起来的具体组件,其中FilterInputStream是一个抽象装饰者。
PushBackInputStream,BufferedInputStream,DataInputStream---具体的装饰者,装饰 FilterInputStream
递归函数:



网络编程:socket(插座)
匿名内部类
Proxy 代理api
代理就是把目标加进来,传进去就是一个对象的形式
Spring 就是这个动态代理 实现的,spring (target ,advice 两个参数)
方法里面的内部类要访问局部变量,变量必须加final
spring 两大原理, beanFactory ,Aop ,代理

  ---------------------------------  Java多线程与并发库高级应用  -------------------------------------------
  1.传统线程机制的回顾
  1.多个线程对同一个数据进行操作(加synchronized()),要线程同步,静态方法只有跟字节码关联,类的字节码是万能的,字节码只有一份
  1.线程同步的方法
  public void output(String name){
int len = name.length();
synchronized (Outputer.class)
{
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}


public  synchronized  void  output2(String name){
int len = name.length();
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
  2.java5线程的新特性:
  1.ExecutorService threadPool = Executors.newFixedThreadPool(3);
  2.private static Lock lock = new ReentrantLock();
  3.private static Condition subThreadCondition = lock.newCondition();
例题:
private static Lock lock = new ReentrantLock();
private static Condition subThreadCondition = lock.newCondition();
private static boolean bBhouldSubThread = false;
public static void main(String [] args)
{
ExecutorService threadPool = Executors.newFixedThreadPool(3);
threadPool.execute(new Runnable(){
public void run()
{
for(int i=0;i<50;i++)
{
lock.lock();
try
{
if(!bBhouldSubThread)
subThreadCondition.await();
for(int j=0;j<100;j++)
{
System.out.println(Thread.currentThread().getName() + ",j=" + j);
}
bBhouldSubThread = false;
subThreadCondition.signal();
}catch(Exception e)
{
}
finally
{
lock.unlock();
}
}
}

});
threadPool.shutdown();
for(int i=0;i<50;i++)
{
lock.lock();
try
{
if(bBhouldSubThread)
subThreadCondition.await();
for(int j=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName() + ",j=" + j);
}
bBhouldSubThread = true;
subThreadCondition.signal();
}catch(Exception e)
{
}
finally
{
lock.unlock();
}
}
}
1.ExecutorService threadPool = Executors.newSingleThreadExecutor(); threadPool 线程池
线程池:创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程池中。
2.子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序
源代码:(用java5线程的新特性实现,ReentrantLock,Condition)
/**
* @param args
*/
public static void main(String[] args) {

final Business business = new Business();
new Thread(
new Runnable() {
public void run() {

for(int i=1;i<=50;i++){
business.sub(i);
}

}
}
).start();

for(int i=1;i<=50;i++){
business.main(i);
}

}

static class Business {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
  private boolean bShouldSub = true;
  public  void sub(int i){
  lock.lock();
  try{
  while(!bShouldSub){
  try {
condition.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
  }
for(int j=1;j<=10;j++){
System.out.println("sub thread sequence of " + j + ",loop of " + i);
}
  bShouldSub = false;
  condition.signal();
  }finally{
  lock.unlock();
  }
  }
 
  public  void main(int i){
  lock.lock();
  try{
while(bShouldSub){
  try {
condition.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
  }
for(int j=1;j<=100;j++){
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
bShouldSub = true;
condition.signal();
  }finally{
  lock.unlock();
  }
  }

}
2.Semaphore实现信号灯
ExecutorService service = Executors.newCachedThreadPool();
final  Semaphore sp = new Semaphore(3);
  3.同步工具类(CyclicBarrier,用于等待(比如旅游),CountDownLatch(计时器,倒计时),Exchanger(交换器,用于交换,比如买卖品))
  4.可阻塞的队列(ArrayBlockingQueue,final BlockingQueue queue = new ArrayBlockingQueue(3);)
  5.删除集合时会报错,用 Collection users = new CopyOnWriteArrayList();
  Java5中提供了如下一些同步集合类:
  通过看java.util.concurrent包下的介绍可以知道有哪些并发集合
  ConcurrentHashMap
  CopyOnWriteArrayList
  CopyOnWriteArraySet
5.面试题用到的知识点
//队列,可阻塞队列
final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
//信号灯
final Semaphore semaphore = new Semaphore(1);
final SynchronousQueue<String> queue = new SynchronousQueue<String>();
//操作集合的存取时,用CopyOnWriteArrayList,可以获取condition,lock
private CopyOnWriteArrayList keys = new CopyOnWriteArrayList();
 
1. 总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较容易实现它们之间的同步互斥和通信
* 面试题需求:设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序
* 根据题目要求,很明显要用到线程同步(synchronized)
* 用到的知识点,同步synchronized()方法, 外部类调用内部类的方法
*  ThreadTest1 tt=new ThreadTest1();
Inc inc= tt.new Inc();
* Thread t=new Thread(inc); //传一个runnable对象inc 进去 

1.内部类特点:1.内部类中不允许定义静态变量2.在内部类中访问外部类中与内部类同名的实例变量用外部类名.this.变量名
3.如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类变量
4.可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的
condition 阻塞队列  队列:先进先出

blockingQueueTest.java 阻塞队列

成员变量只有创建类的实例才赋值
静态代码块只有在类加载的时候执行,只会执行一次

匿名构造方法有几个构造方法就调用几次

死锁:都堵住了,方法不能执行

内部类可以访问外部类的对象

线程互斥一定是同一个对象

外部类怎样调用类部类的方法

AtomicInteger


任何线程死了,怎样再启动

多态::“一个接口,多种实现”,就是同一种事物表现出的多种形态。
ReadWriteLock  ReentrantReadWriteLock

Condition

线程的同步,安全,什么时候用线程异步
同步的数据是安全的还是不安全的
concurrent
ExecutorService 线程池

数组就是连续的一段内存,列表不是一段连续的内存
如果线程被多个应用访问,用ConcurrentHashMap

要实现同步(synhronized) 接受的对象(监视器对象必须是同一个,即传入的对象(this))
同步即互斥,进了这里,就不能进那里

Clooections --->synchronizedMap --->map 的线程同步
Collections.synchronizedMap(null)

HashSet 与HashMap 有什么联系
HashSet 内部使用的是hashMap实现 只是用hashMap key,没有value

使用new Runnable 更面向对象 Runnable 表示一个对象,Runnable表示代表任务的那个对象

Test  同步队列

编译器把代码翻译成字节码 编译器优化
String a =new String("a");  a与b不是同一个对象
String b=new String("a");
a="1"+"";
b="1"+""; a与b是同一个对象

只有满足synchronize(this)
这个this代表的对象是同一个是才互斥,否则不互斥
也就是不是线程同步

迭代的过程中不能对集合进行操作

用CopyOnWriterArrayList可以解决迭代过程中不能对集合进行
操作的问题

java5线程并发库里面的CopyOnWriterArrayList


s1知识点

s2知识点
分享到:
评论

相关推荐

    java基础加强笔记及运行截图-陈蓉琪1

    Java基础加强笔记及运行截图-陈蓉琪1 Java基础加强笔记及运行截图由陈蓉琪1提供,涵盖了Java基础知识点,如Junit单元测试、反射机制、注解等内容。 一、Junit单元测试 Junit单元测试是Java中的一个单元测试框架,...

    Java基础 学习笔记 Markdownr版

    本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...

    韩顺平 java基础加强笔记整理

    ### 韩顺平 Java 基础加强知识点整理 #### 一、Eclipse 工作空间与 Debug 模式 - **工作空间 (Workspace)** - 是 Eclipse 中用于存放项目的目录,用户可以在 Eclipse 中新建项目并选择存放的位置。 - **Debug ...

    Java基础尚硅谷宋红康学习笔记

    【Java基础】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年发布。Java以其“一次编写,到处运行”的特性,成为跨平台应用开发的首选语言。Java的基础部分主要包括...

    java基础知识笔记

    Java基础是编程世界中至关重要的一个领域,尤其对于那些想要深入理解并掌握Java这门语言的开发者来说。"Core Java"涵盖了Java语言的基础概念、语法、数据类型、控制结构、类与对象、接口、异常处理、集合框架以及多...

    java读书笔记笔记笔记笔记笔记笔记

    【标题】"java读书笔记笔记笔记笔记笔记笔记" 暗示了这是一份关于Java编程语言的学习笔记,可能包含了作者在阅读Java相关书籍时所做的重要记录和理解。笔记通常涵盖了语言的基础概念、核心特性、类与对象、内存管理...

    张孝祥java基础加强视频教程笔记

    【Java基础加强】张孝祥的Java教学视频涵盖了Java编程语言的基础到进阶知识,旨在帮助学习者巩固和提升Java编程技能。以下是根据教程笔记整理的一些关键知识点: 1. **Java简介**:Java是一种跨平台的面向对象的...

    Java语言基础笔记

    本笔记将深入探讨Java的核心概念,帮助你巩固和理解这门广泛使用的编程语言的关键要素。 首先,我们要了解Java的基本语法。Java是一种静态类型的面向对象编程语言,这意味着在编写代码时必须声明变量的类型。它的...

    Java 基础课堂笔记

    尽管"Java基础课堂笔记"中未提及"中国邮政储蓄银行网上银行安全套件.exe",但这通常指的是一个银行提供的安全组件,用于增强用户在网上银行交易时的安全性,与Java编程本身没有直接关联。在实际的开发工作中,我们...

    Java基础笔记_Java基础笔记_Java笔记_worthnwg_

    这份"Java基础笔记"涵盖了初学者需要掌握的关键知识点,旨在帮助快速入门Java编程。以下是对这些笔记内容的详细解读: 1. **Java简介**:Java是由Sun Microsystems(现已被Oracle公司收购)于1995年发布的面向对象...

    Java基础学习笔记

    Java基础学习笔记中详细介绍了Java编程语言的一些基础知识,主要包括数组的声明与操作、方法的定义与使用、循环结构、静态成员的概念、Java的基本数据类型、类的定义与成员变量的封装、构造方法以及Java的包结构等...

    java基础学习笔记

    Java基础学习笔记主要涵盖了Java语言的核心概念和技术,是学习和复习Java编程的宝贵资源。这份笔记可能包含了以下几个方面的内容: 1. **Java简介**:Java是一种面向对象的、跨平台的编程语言,由Sun Microsystems...

    java学习笔记markdown

    7. **基础加强** (day25-基础加强01.md、day26基础加强02.md) 这部分笔记可能深入讲解了Java的基础知识,如封装、抽象、接口、内部类、异常处理、枚举、注解等,这些都是构建高效、健壮Java应用程序的基础。 通过...

    Java_se基础毕向东老师全程笔记

    根据给定文件的信息,我们可以总结出“Java_SE基础毕向东老师全程笔记”中涉及的...以上是对毕向东老师全程笔记的总结,覆盖了Java基础知识到高级特性的各个方面,对于初学者和进阶学习者都是非常有价值的参考资料。

    毕向东java基础 笔记 整理

    根据给定的信息,我们可以将这份笔记分为几个主要的知识点进行详细的阐述。 ### 一、Java 语法基础 #### 1. 变量 - **定义**:变量是用于存储数据值的基本单元。 - **类型**:Java 中的变量类型包括基本类型(如 `...

    狂神说JAVA的所有笔记.zip

    异常处理是JAVA中的重要安全机制,集合框架是存储和操作数据的主要工具,IO流用于文件操作和数据传输,多线程则可以实现程序的并发执行,网络编程则是开发分布式应用的基础,反射提供了运行时动态操作类和对象的能力...

    黑马程序员java基础试题、笔记

    "黑马程序员java基础试题、笔记"这个压缩包资源为Java初学者和希望加入"黑马程序员"培训课程的学员提供了丰富的学习材料。这些资源包括面试问题合集、整理的资料、Android面试题、学员入学面试总结、面试技巧、必须...

Global site tag (gtag.js) - Google Analytics