------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
1. 一些简写:ide——>itegrity development environment
perspective:透视图
调试:1. 定制断点
2. 在断点开始出右键点击watch
2. 静态导入:jdk1.5新特性
import 语句可以导入一个类或某个包中的所有类。
import static 语句导入一个类中的某个静态方法或所有静态方法
3. jdk1.5新特性:
可变参数:即参数数不固定
可变参数的特点;
只能出现在参数列表的最后
...位于变量类型和变量名之间,前后有无空格都可以
调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中
以数组的形式访问可变参数
例子
public static int add(int x, int ... args){}
增强for循环for(type 变量名:集合变量名){}
基本数据类型的自动装箱与拆箱
自动装箱;Integer num =12;
自动拆箱:System.out.println(num+12)
自动装箱中:Integer l1 =12;
Integer l2 =12; 即当数据在-128--127时l1=l2;其他不相等
此时叫做享元模式(flyweight)有很多个小的对象,把他们变成一个
对象
枚举:枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译 器就会报错,枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量
的方式在开发阶段无法实现这一目标。
public class WeekDay
{
private WeekDay(){}
public final static WeekDay SUN = new WeekDay();
public final static WeekDay MON = new WeekDay();
public WeekDay nextDay()
{
if(this == SUN)
{
return MON;
}
else
{
return SUN;
}
public String toString()
{
return this==SUN?”SUN”:”MON”;
System.out.println(WeekDay.nextDay());
}
}
}
public class EunmTest
{
public static void main(String[] args)
{
WeekDay weekDay = WeekDay.MON;//这就是枚举,只能调用上面 //WeekDay定义好的。
}
}
范围类中也可以写内部类定义各自对象的子类即:内部类
public final static WeekDay SUN = new WeekDay()
{
public WeekDay nextDay()
{
return MON;
}
}
public abstract WeekDay nextDay();//必须抽象方法,
用抽象方法定义nextDay就将大量的if和else语句转移成了一个个独立的类
总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象
上面的枚举是自己写的,但是jdk已经封装啦这样的类如:
可以写在当前文件::public enum WeekDay{SUN, MON,TUE,WED,THI,FRI,SAT}
这样的可以直接自动转换成字符串,还可以有自己的名字,排行,等
WeekDay.valueof(“SUN”.toString())将传来的变量转换成
对象
WeekDay.values().length遍历对象
注意定义枚举的构造方法必须在对象之后,构造方法必须是私有 的。还有就 是枚举的对象可以用类的子类来实现,如果只有一个成员时,就可以作为一种 单利的实现方式。
4. 反射:
大写的Class:java程序中的各个java类,他们属于同一类事物,可以用一个类来 描述这类事物就是Class:它描述了类的名字,累的访问属性,类的所属包名,字 段名称的列表,方法名称的列表等
Class cls1 = Date.class//字节码
如何得到各个字节码对应的实例对象
类名.class 例:System.class
对象.getClass() 例:new Date().getClass
Class.forName(“类名”) 例:Class.forName(“java.util.Date”)
数组类型的Class实例对象,Class.isArray();
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如
int[],
反射:就是把java类中的各种成分映射成相应的java类
Constructor类代表某个类的一个构造方法
得到某个类所有的构造方法:
例子:Constructor[] constructors = Class.forName(“java.lang.String”).getConstructors();
得到某一个构造方法:Constructor[] constructors = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
创建实例对象:
通常方法:String str = new String(new StringBuffer(“sbc”));
反射方法:String str = (String)constructor.newInstance(new StringBuffer(“abc”))
Class.newIntance()方法:
String obj = (String)Class.forName(“java.lang.String”).newIntance()
该方法内部先得到默认的构造方法,然后用该构造方法创建实例 对象
Field类:代表某个类中的一个成员变量
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField(“y”);
fieldY.get(pt1)///取值
Field fieldX = pt1.getClass().geDeclaredtField(“x”);
fieldX.setAccessible(true);//暴力反射
fieldX.get(pt1)
Method类:代表某个类中的一个成员方法
得到类中的某一个方法:
Method charAt=Class.forName(“java.lang.String”).getMethod(“charAt”,int.Class)//int.Clas s的个数就是参数的个数
调用方法:
通常方法Str.charAt(1);
反射:System.out.println(charAt.invoke(str,1))。如果invoke()一个参数
为null,该Method对象对应一个静态方法
数组反射:具有相同维数和元素的数组属于同一个类型,即具有相同的Class 实例对象。
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类
对应的Class
基本类型的一维数组可以被当做Object类型使用,不能当做Object()类型
使用,非基本类型的一维数组,既可以当做Object类型使用,又可以当做 Object[]类型使用
Arrays.asList()方法可以处理int[]和String[]的差异
Array工具用于完成对数组的反射操作
注意:当一个对象被存储紧HashSet集合中以后,就不能修改这个对象中的那
写参与计算的哈希值的字段了,否则就与最初不同,可能造成内存泄露。
private static void changeStringValue(Object obj)
{
fied[] fields = obj.getClass().getFields();
for(Field field : fields)
{
if(field.getType()==String.class)
{
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('a', 'b');
field.set(obj,newValue);
}
}
}
5. 反射的作用---->实现框架功能
框架与工具类区别?
工具类被用户的类调用,而框架则是调用用户提供的类。
框架要解决的核心问题?
因为在写程序时无法知道要被调用的类名,所以,在程序中无法直接new某个类
的实例对象,而要用反射方法来做。
框架要调用配置文件:配置文件用工程中的右键点击File,File name:***.properties
里面className=java.util.ArrayList
注意:getRealPath();得到路径
例子;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;
/*
* 反射框架
* 先建立配置文件已properties为后最名*/
public class Fanshe
{
public static void main(String[] args) throws Exception
{
InputStream ips = new FileInputStream("config.properties");
/*
* Fanshe.class.getClassLoader().getResourceAsStream("cn/itcast/day/config.properties")
* 加载配置文件
* 在一种方法
* InputStream ips = Fanshe.class.getResourceAsStream(config.properties);//不需要写路径
* */
Properties props = new Properties();//加载配置文件
props.load(ips);
ips.close();
String className = props.getProperty("className");
Collection collections = (Collection)Class.forName(className).newInstance();
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(4,4);
Collections.add(pt1);
Collections.add(pt2);
System.out.println(collections.size());
}
}
6. 内省:(IntroSpector)用于对javaBean操作
JavaBean特殊的java类
gettime-->属性名time//如果第二个字母是小的,则把第一个字母变成小的
setTime-->属性名 time
getCPU-->属性名CPU
javaBean是一种特殊的java类,主要用于传递数据信息,这种java类中低端方法主 要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个javaBean中,这种 JavaBean的实例对象通常称之为(Value Object,简称VO),这些信息在类中用私有字 段存储,读取和设置用setter和getter方法来确定。
总之:一个类被当作JavaBean使用时,JavaBean的属性是根据方法名推断出来的,它 根本看不到java内部的成员变量
例子:
import java.beans.PropertyDescriptor;
/*
* 内省服务javaBean*/
public class IntroSpectorTest
{
public static void main(String[] args) throws Exception
{
ReflectPoint pt1 = new ReflectPoint(3,5);//就是另个类中定义啦get和set方法
String propertyName = "x";
//内省访问x
PropertyDescriptor pd =new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
System.out.println(retVal);
PropertyDescriptor pd2 =new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX =pd2.getWriteMethod();
methodSetX.invoke(pt1,7);
System.out.println(pt1.getX());
}
}
用Beanutls工具包先get原来设置好的属性,在将器set为一个新值,get属性返回
结果字符串,set属性可以任意类型,通常字符串。
用PropertyUtils类先get原来设置好的属性,在将其set新值,get属性返回结果为
该属性本来的类型,set属性只接受该属性本来的类型
拷贝jar包要建Fold(目录)拷贝进去,然后构建路径:右键构建路径
还要拷贝日志包,步骤和上面一样,
构建好路径后就可以用:
System.out.println(BeanUtils.getProperty(pt1,”x”));//get方法
BeanUtils.setProperty(pt1,”x”,”9”);//set方法设置为9,但是为字符串
7. jdk1.5新特性:java提供的几个基本注解:一个注解就是一个类
@SuppressWarning(“deprecation”)//运行到RetetionPolicy.SOURCE 告诉编译 工具,我使用了过时的方法
@Deprecated//运行到RetetionPolicy.RUNTIME 直接在刚才的类中增加一个方法, 并加上@Deprecated标注,在另外
一个类中调用这个方法,可以调用过时方法
@Override 运行到RetetionPolicy.RUNTIME,当你覆盖父类方法时,找不出错是, 加上这个注解,可以确定错
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记 ,没加
等于没有某种标记,看标记,就去干相应的事
@Retention源注解其三种取值:作用是注解到那个生命周期
RetetionPolicy.SOURCE RetetionPolicy.CLASS RetetionPolicy.RUNTIME 分别对应java源文件,class文件,内存字节码
@Target({ElementType.METHOD,ElementType.TYPE})用于说明注解用到哪里
8. 定义基本类型的属性和应用属性
在注解中增加Stringcolor()
@MyAnnotation(color=“red”)
用反射方式获得注解对应的实例对象后,在通过该对象调用属性对应的方法
MyAnnotation a =(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color())
为属性指定缺省值:
String color()default “yellow”
value属性:
String value() default “z***”
数组类型的属性
int[] arrayAttr()default{1,2,3}
@MyAnnotation(arrayAttr={1,3,4})
如果数组属性中只有一个元素,这时属性值部分可以省略大括号
枚举类型的属性
EnumTest。TrafficLamp lamp();
@MyAnnotation(lamp= EnumTest.TrafficLamp.GREEN)
注解类型的属性
MetaAnnotation annotationAttr()default@MetaAnnotation(“***”)
@MyAnnotation(annotationAttr=@MetaAnntation(“yyy”))
9. jdk1.5新特性泛型
泛型是提供给javac编译其使用的,可以限定集合中的输入类型,让编译器挡住源 程序中的非法输入,编译器编译带类型说明的集合时会去掉类型信息,是程序运行 效率不受影响,对于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,
就可以往某个泛型结合中加入其它类型的数据,例如用反射得到集合,在调用其
add方法即可
泛型术语
ArrayList<E>整个称为泛型类型
ArrayList<E>中E称为类型变量或类型参数
整个ArrayList<Integer>称为参数化的类型,而Interger类型参数的实例
ArrayList<Integer>中<>念typeof
ArrayList称为原始类型
参数化类型与原始类型的兼容性
参数化类型可以引用一个原始类型的对象,编译器报告警告
Collection<String> c = new Vector()
原始化类型可以引用一个参数化类型对象,编译器报告警告
Collection c = new Vector<String>()
参数haunted类型不考虑类型参数的继承关系
Vector<String> v = new Vector<Object>();这是错的
在创建数组实例时,数组元素不能使用参数化的类型
如Vector<Integer> vectorList[] = new Vector<Integer>[10]这是错的
泛型<?>代表任意参数化类型
总结:使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主 要用引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法
限定上下界:Vector<?extends Number> v = new Vector<Integer>();
Vector<?super Integer> v = new Vector<Number>();
只有应用类型才能作为泛型方法的实际参数,基本类型会报错,但是可以把对 象外的基本数据类型自动转换(自动拆箱和装箱)成引用类型,除数组外,如
数组本身就是对象,不能自动拆箱和装箱啦
普通方法,构造方法和静态方法中都可以使用泛型,也可以用类型变量
标识异常,称为参数化的异常,可以用于方法的throws列表中,但是不能用
与catch中,但是必须是异常的子类,<t extends Exception>
泛型中可以同时又多个类型参数,在定义他们的尖括号中用逗号分。
***类型参数的推断:编译器判断泛型方法的实际类型参数过程为类型推断。
1.当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被 应用,那么根据调用方法时该处的实际应用类型来确定,
2.当某个类型变量在整个参数列表中所有参数和返回值中的多处被应用 了,如果调用方法时这多处的实际应用类型都对应一宗类型来确定
3.当某个类型变量在整个参数列表中所有参数和返回值中的多处被应用 了,如果调用方法时这多处的实际应用类型对应到了不同的类型,且没有
使用返回值,这时去多个参数中的最大交集类型
4.当某个类型变量在整个参数列表中所有参数和返回值中的多处被应用 了,如果调用方法时这多处的实际应用类型对应到了不同的类型,,并且有返回值,这时候优先考虑返回值的类型,
5.参数类型的类型推断具有传递性,
定义泛型类型:即在类名后定义泛型,作用于整个类
如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的
泛型类型要保持同一个实际类型时,这时候就要采用泛型类型的方式进行
定义,也就是类级别的泛型
在对泛型进行参数化时,类型参数的实例必须是引用类型,不能使基本类型。
当一个变量被声明为泛型时,只能被实例变量和方法调用,而不能被静态变量
和静态方法调用,应为静态成员被所有参数化的类所共享。
10. 类加载器:加载类的工具、默认的三个主要类加载器,每个类负责加载特定位置的类。
BootStrap,ExtClassLoader,AppClassLoader
类加载器也是java类,本身被加载器加载,先有一个类加载器不是类,正式 BootStrap
java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每 个类装载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统类装载 器为其父级类加载
查看类是那个类加载器加载:
ClassLoaderTest.class.getClassLoader().getClass().getName()
类加载器的委托机制:到底选哪个类加载器
首先当前线程的类加载器去加载线程的第一个类
如果类中A中引用了类B,java虚拟机将使用加载类A的类装载器来加载类B
还可以直接调用ClassLoad.loadClass()方法来指定某个类加载器去加载某 个类。
每个来加载器加载类时,又先委托给其上级类加载器
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不抛
ClassNotFoundException
编写自定义类加载器必须继承ClassLoad,先去找祖先,而自己只需写自己干的
代码,解密需要覆盖findClass
例子:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
/*
* 类加载器*/
public class ProxyTest
{
public static void main(String[] args) throws Exception
{
Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
/*
* $proxy0()
* $Proxy0(InvocationHandler,int)
* */
System.out.println("--------begin constructors list---------*--");
Constructor[] constructors = clazzProxy1.getConstructors();
for(Constructor constructor : constructors)
{
String name = constructor.getName();
StringBuilder sBuilder =new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams =constructor.getParameterTypes();
for(Class clazzParam : clazzParams)
{
sBuilder.append(clazzParam.getName()).append('c');
}
if(clazzParams!=null&&clazzParams.length!=0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
System.out.println("--------begin methods list---------*--");
Method[] methods = clazzProxy1.getMethods();
for(Method method : methods)
{
String name = method.getName();
StringBuilder sBuilder =new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams =method.getParameterTypes();
for(Class clazzParam : clazzParams)
{
sBuilder.append(clazzParam.getName()).append('c');
}
if(clazzParams!=null&&clazzParams.length!=0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
System.out.println("--------begin instance ---------*--");
Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
class MyInvocationHander1 implements InvocationHandler
{
public Object invoke(Object proxy, Method method, Object[] arg2) throws Throwable {
// TODO 自动生成方法存根
return null;
}
}
Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHander1());
proxy1.clear();
//proxy1.size();
}
}
11. 代理
要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,要用到
代理。
编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同
方法,并在调用方法时加上系统功能代码。
如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置
文件中配置是使用目标类,还是代理类,这样以后很容易切换。
面向方面的编程:简称:AOP,AOP的目标就是要使交叉业务模块化,可以采用将切
面代码移动到原始方法的周围,
安全,事物,日志等功能要贯穿到好多个模块中,所以,它们就是交叉业务
重要原则:不要把供货商暴露给你的用户
动态代理技术:
jvm可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理 类,即动态代理类。
jvm生成的动态类必须实现一个或多个接口,所以,jvm生成的动态类只能用作 具有相同接口的目标的代理
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理, 所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB
库
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的 结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法之前后
4.在处理目标方法异常的catch快中
创建动态类涉及到三个方面
生成的类中有哪些方法,通过让器实现哪些接口方式进行通告
产生的类字节码必须有个关联 类加载器对象
生成的类中的方法的代码也的有我们提供,把我们的代码写在一个约定好 的接口对象方法中,把InvocationHandler传给他
调用代理对象涉及三要素;对象,方法,参数
动态类的实例对象,结果null,打印size()方法出行异常,
12.学习心得体会
掌握常用的高新技术;知道一些简写,重点
学习泛型,注解,代理,可变参数,知道怎么用,了解新技术
比老技术的优点
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------