`
lvwenwen
  • 浏览: 930501 次
  • 性别: 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基础加强笔记整理

    内容包括eclipse常用快捷键,可变参数,枚举,反射,泛型等等

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

    基础加强练习笔记Junit单元测试@Before初始化方法 用于资源申请 所有测试方法在执行之前都会先执行该方法@After释放资源方法 在所有测试方法执行完毕

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

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

    Java基础最全笔记文档

    Java基础笔记分为 Java基础篇 和 Java加强篇 Java基础篇包括: 1. Java环境搭建、Java快速入门、IDEA开发工具 2. Java基础语法、类型转换、运算符、Scanner 3. 分支结构、循环结构、随机数 4. 数组详解、Debug工具...

    Java学习笔记7.0

    《Java JDK6学习笔记》是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型...

    Java基础学习笔记

    Java基础的学习至关重要,这是本人根据马士兵老师视频讲解所制作的文档,文档有本人设计的目录,方便各位的阅读,代码加上注释使其可读性增强。重要的是在目录的结尾部分给出了视频及源码的链接,进一步提升各位学习...

    传智播客张孝祥java高新技术 笔记ppt

    自己整理的关于传智播客java基础增强的笔记,包括部分代码。

    java学习笔记 初学者必读

    17.2. 增强的for循环 17-66 17.3. 自动装箱和自动拆箱 17-69 17.3.1. 在基本数据类型和封装类之间的自动转换 17-69 17.4. 类型安全的枚举 17-70 17.5. 静态引入 17-71 17.6. C风格的格式化输出 17-72 17.7. Building...

    java内部学习笔记.docx

    2.16 Java基础其他注意事项 14 面向对象 16 3.1类 16 3.2对象 16 3.3包 16 3.4方法及其调用 17 3.5引用 17 3.6访问控制(封装) 17 3.7构造器 17 3.8 super()、super.和 this()、this. 18 3.9重载和重写 19 3.10...

    java学习笔记–java基础

    java基础1.1 输入输出用户交互Scanner用户交互Scanner进阶1.2 基本数据类型基本数据类型类型转换变量,常量,作用域运算符补充:包机制补充:JavaDoc1.3 顺序结构1.4 循环结构while循环do-while循环for循环增强型for...

    java学习笔记-java思维导图流程图表格整理

    Java基础 1 注释 1 单行注释 1 多行注释 1 文档注释 1 标识符和关键字 2 数据类型 4 类型转换 7 变量 9 基本运算符 10 包机制 12 Javadoc 12 使用命令行生成 12 使用idea生成 12 Java流程控制 13 用户交互scanner 13...

    旨在打造在线最佳的 Java 学习笔记.rar

    在学习Java中,常常碰到...这套JavaSE教程基于Java17讲述,从零基础出发,讲解Java编程的基础知识和实践技巧,涵盖了Java编程的方方面面。 原文链接:https://blog.csdn.net/2301_78369729/article/details/130947974

    JavaSE基础学习笔记

    JavaSE 星辰学习笔记 简介 如何高效的学习Java 案例:创建一个博客网站typecho 基础 Java程序运行机制 数据类型 变量 变量作用域 常量final 变量的命名规范 运算符 for循环 增强for循环 break continue 练习 Java的...

    JAVA WEB 新手入门笔记

    一、 JavaScript 二、 数据库单表 三、 数据库多表 四、 事务的管理 五、 JDBC 六、 JDBC连接池 七、 DBUtils 八、 Tomcat & Http 九、 Servlet & request & response ...十八、 框架基础加强 十九、 补充

    韩顺平Java重点标注版

    将一些重点进行了区分和标注,增加了笔记的...适合没有基础的小伙伴和一些有一定基础但是不懂得怎么运行的小伙伴,还有一些学了一段Java,但是长时间未练习的小伙伴; 韩顺平老师是我目前认为将Java最细致的老师之一;

    java基础学习笔记之java oop高级java异常处理机制、集合、文件操作、序列化与反序列化、字符串处理(三)

    4.异常处理的作用:增强的稳定性、健壮性. 5.java异常处理的关键字 try、catch、finally、throw、throws 代码示例 package 理解异常; import java.io.IOException; import java.util.Scanner; import org.

    JAVAWeb全课程笔记( html版)

    目录 HTML总结 CSS总结 JavaScript总结 DOM总结 tomcat服务器 servlet基础 Request&Response编程 Cookie&Session XML语言 JSP技术入门 EL表达式语言 JSTL标签库: JSP标准标签库 ...Java基础加强 JQuery Ajax JSON

Global site tag (gtag.js) - Google Analytics