java高新技术
eclipse的使用技巧
javaee
ide -->itegrity debelopoment environment 集成开发环境
jms
jmx
jndi
preferences 喜好 首选项
switch workspace 切换工作间
perspective 透视图
面试技巧 包名 编码规范
debug watch 可以看变量的值(老师的普通话啊!!!)
透视图是视图的集合
如何设置单个工程的javac和java
工程右键--preference--java--compiler
模版代码设置
preferences--editor--Templates
静态导入(1.5新特性)
import语句可以导入一个类或或某个包中的所有类
import static语句导入一个类中的某个静态方法或所有静态方法
可变参数(1.5新特性)
方法参数个数不固定
增强for循环(1.5新特性)
语法for(Type obj:集合变量名){。。。}
注意事项:
迭代变量必须在()中定义!
集合变量可以是数组或实现了Iterable接口的集合类
基本数据类型的自动装箱与拆箱
Integer iObj = 3; //1.4之前是报错的
装箱:自动将一个基本类型装箱成一个
Integer类型再赋给iObj变量
System.out.println(iObj+12);
拆箱:将引用类型转换成基本类型再进行假发运算
对于基本数据类型的整数,如果数据在一个字节(-128 - 127)之内,装箱后缓存到池中,以反复使用。
享元模式:如果很多很小的对象,他们有很多属性相同,就可以将其编程一个对象,不同的属性变成方法的参数,称之为外部状态,相同的属性称之为内部状态
节省资源flyweight
**************************************
**************************************
枚举(1.5新特性)
枚举就是要让某个类型的变量的求职只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
package com.sun.day1;
public abstract class WeekDay {
private WeekDay(){}
public final static WeekDay SUN = new WeekDay(){
@Override
public WeekDay nextDay() {
// TODO Auto-generated method stub
return MON;
}
};
public final static WeekDay MON = new WeekDay(){
@Override
public WeekDay nextDay() {
// TODO Auto-generated method stub
return SUN;
}};
/*public WeekDay nextDay(){
if(this == SUN)
return MON;
else
return SUN;
}*/
public abstract WeekDay nextDay();
public String toString(){
return this == SUN?"Sunday":"Monday";
}
}
将大量的if else语句转移成了一个个独立的类
枚举的基本应用:
枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.gteClass().getName和WeekDay.class.getName()
1.元素列表必须在所有成分之前
2.元素列表后要是有其他部分 必须加分号
3.构造方法必须为private
4.枚举元素后加上括号指定其调用的构造方法
如果枚举只有一个成员时,就可以作为一个单例的实现方式。
反射(1.2不是1.5新特性)
反射的基石 Class类
Class--->代表这类实物的Java类名就是Class
Java类用于描述一类事务的共性,该类实物有什么属性,没有什么属性,至于这个属性的值是什么,则室友这个类的实例对象来确定的,不太能够的类实例对象有不同的属性值。Java程序中的各个Java类,他们是否属于同一类事务,是不是可以用一个类来描述这类事务呢?这个类的名字就是Class,要注意与小写class关键字的区别。Class类描述了哪些方面的信息呢?类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表,等等。
得到实例对象的字节码(Class类型)
类名.class,例如,System.class
对象.getClass(),例如,new Date().getClass()
Class.forName("类名"),例如,Class.forName("java.util.Date")
Class.froName("类名") 有两种情况,一种是在内存中找到已存在的字节码,另一种是创建新的对象的字节码
九个预定义Class对象
boolean,byte,char,short,int,long,float,double(8个基本数据类型)和void
Class c1 = void.class;
参看Class.isPrmitive(是否是原始类型)方法的帮助
int class = Integer.TYPE;
(TYPE所包装的基本数据类型)
判断是否是数组类型的Class实例对象Class.isArray()
总之,只要是在源程序中出现的类型,都有格子的Class实例对象,例如,int,void...
反射
反射就是把Java类中的各种成分映射成相应的java类。
例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像七成是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用相应类的实例对象来表示,塔门是Field、Method、Contructor、Package等等。
一个类中的每隔成员都可以用相应的反射API类的一个实例对象来表示。
Constructor类
代表某个类中的一个构造方法
得到某个类的所有的构造方法
Construstor[] constructors = Class.forName("java.lang.String").getConstructors();
得到某个类中的一个构造方法
Constructor constructor = Class.forName("java.lang.String").getContructor(StringBuffere.class);
获得方法时要用到类型
创建实例对象
通常方式:String str = new String(new StringBuffer("abc"));
反射方法:String str = (String)constructor.newInstance(new StringBuffer(StringBuffer.class));
调用获得的方法时要用到上面相同的实例对象
Class.newInstance();
newInstance() 反射调用构造方法创建对象
例子:String obj =(String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
该方法内部的具体代码是调用默认的构造方法,再用构造方法创建类对象。用到了缓存机制来保存默认构造方法的实例对象
反射会导致性能下降
Field类
getFile()方法获取非私有变量
getDeclaredField()方法获取声明的变量
setAccessable(boolean b)暴力访问,设置可否访问私有变量
作业:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b”改成“a”。
private static void changeStringValue(Object obj)throws Exception{
Field[] fields = obj.getClass().getFields();
for(Field field :fields){
if(field.getType() == String.class){
if(!field.isAccessible())
field.setAccessible(true);
String strValue = (String)field.get(obj);
strValue = strValue.replace('b', 'a');
System.out.println(strValue);
field.set(obj, strValue);
}
}
}
Method类
代表某个类中的一个成员方法
得到类中的某一个方法
例子:Method charAt = Class.forName("java.lng.String").getMethod("charAt", int.class);
调用方法
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str, 1));
如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢》说明该Method对象对应的是一个静态方法!
jdk1.4和jdk1.5的invoke方法的区别
jdk1.5:public Object invoke(Object, Object...args)
jdk1.4:public Object invoke(Object obj, Object[] args)
即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每隔元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用jdk1.4改写为charAt。invoke(“str”, new Object[]{1})形式
用反射方式执行某个类中的main方法
目标:
写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args), 通过反射的方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每隔元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照那种语法进行处理呢?jdk1.5可定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用直接传递数组的方式,javac只把它当作jdk1.4的语法进行丽姐,而不把它当作jdk1。5的语法解释,因此会出现参数类型不对的问题。
解决办法
manMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"});,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会将数组打散成若干个参数了
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class
基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组即可以当作Object类型使用,也可以当作Object[]类型使用。
Arrays.asList()方法处理int[]和String[]时的差异
Array工具类用于完成对数组的反射操作
怎么得到数组中的元素类型?
无法判定数组的类型
只能获取数组内的元素 在判断数组内元素的类型