01.eclipse操作技巧
设置快捷键:Preference—>General—>Keys—>Content Assist—> Alt+/
JDK高版本能运行低版本编译的,反之不可以
代码模板技巧:Preference—>Java—>Editor—>Templates—>
02.JDK5新特性
1)静态导入—>如:import static java.lang.Math.*;
2)可变参数、增强的for循环(for(type变量名:变量集合 {...}))
public static int add(int x, int ... args) //可变参数格式{
int sum = 0;
/*
for(int i=0; i<args.length; i++) {
sum += args[i]; //需要以数组的形式访问可变参数
}
*/
//增强的for循环
for(int arg:args) {
sum += arg;
}
return sum;
}
3)基本数据类型的自动拆箱与装箱:
享元设计模式(flyweight)
例:Integer a=13;Integer b=13; System.out.print(a==b);结果true
Integer a=213;Integer b=213; System.out.print(a==b);结果false
因为在Integer装入数据在(-128~127)之间,数很小,频率可能会很高,没必要每一次都创建一个对象,自动放在缓存中,一旦再出现直接在缓存里面拿。这是一种设计模式。
4).枚举
a)带有构造方法的枚举 b)带有抽象方法的枚举
实例: public enum TrafficLamb {
RED(5) {
public TrafficLamb nextLamb() {
return YELLOW;
}
},
YELLOW(5) {
public TrafficLamb nextLamb() {
return GREEN;
}
},
GREEN(5) {
public TrafficLamb nextLamb() {
return RED;
}
};
public abstract TrafficLamb nextLamb();
private TrafficLamb(int time) {this.time = time}
}
03.反射
1)反射的基石—>Class类:java类同属于一类事物,Class就是描述这些的java类名,即 [java类—>Class]。
得到的Class类型如cls1为字节码:如下 String str1 = "abc";
Class cls1 = String.Class; //方法1: 类名.class
Class cls2 = str1.getClass(); //方法2: 对象.getClass()
Class cls3 = Class.forName("java.lang.String");//方法3:意思是返回类名的字节码加载到缓存
9个预定义的Class实例对象:
8个基础数据类型(boolean、byte、char、short、int、long、float、double)和(void):
Class cls = int.class//Class cls = void.class;
相同【数据类型】字节码加载到缓存,是同一段字节码,相等
System.out.println(cls1 == cls2); //true
System.out.println(cls1 == cls3); //true
System.out.println(cls1.isPrimitive());//是否是基础数据类型 true
System.out.println(int.class.isPrimitive());//true
System.out.println(int.class == Integer.class);//false
System.out.println(int.class == Integer.TYPE);//Interge所包装的数据类型true
System.out.println(int[].class.isPrimitive());//false
System.out.println(int[].class.isArray());//true
2)反射类就是吧java类中的各种成分映射成相应的java类:
用反射得到各种对象字节码, 再调用Class类中各种方法,去应用。
3)构造方法的反射应用(Constructor)
相当于实现这句//new String(new StringBuffer("abc"));
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str2 = (String)constructor1.newInstance(/*"abc"//不行*/new StringBuffer("abc"));
//newInstance()提供了一个快捷途径
System.out.println(str2.charAt(2));//结果:c
4)成员变量的反射(File)
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");//构造方法中y公有
//fieldY的值是多少?是5,错!fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");//x为私有,所以直接不能读取,用getDeclaredField
fieldX.setAccessible(true); //暴力反射
System.out.println(fieldX.get(pt1));
要点细节:在这里用"=="因为对应的就是缓存中相同字节码,"equals"也能对对,但不专业
//if(field.getType().equals(String.class)){
if(field.getType() == String.class){ }
5)成员方法的反射(Method)
//得到String中参数为int型的charAt方法,在调用,invoke中传的是调用该方法的对象和参数
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1, 1));
System.out.println(methodCharAt.invoke(str1, new Object[]{2}));
对接收数组参数的成员方法进行反射
【main是静态方法,不需要对象调用,用null】
//TestArguments.main(new String[]{"111","222","333"});
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
//mainMethod.invoke(null, new new String[]{"111","222","333"});//【不能行】
//上一语句:【细节】1.5以后可变参数,为支持1.5以前,自动将String[]解包为了三个字符串,但main方法参数为一个数组,所以出错了。
//mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});//可以
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});//对的
6)数组的反射的应用
**相同数据类型和维数的数组属于同一类型
** int[] a = new int[3];//调用getSuperclass()得到的数组的父类名java.lang.Object;
System.out.println(a1.getClass().getSuperclass().getName());
**基本以为数组可以当做Object类使用,但不能作为Object[]使用。——非基本类型的数组都可以。
**Arrays.asList()处理int[]和String[]时的差异
**Array工具类用于完成对数组的反射操作
7)【hashcode方法的作用:内存泄露问题:】
当一个对象被存进HashSet集合中以后,就不能修改这个对象中参与计算哈希值的参数了。否则就会找不到原来的。
8)反射的作用实现框架功能
框架概念
反射开发框架的原理: 配置文件config.properties
9)用类加载器的方式管理资源和配置文件:
//InputStream ips = new FileInputStream("config.properties");//【相对路径:实际开发不要用】
/*getRealPath();//金山词霸/内部
一定要记住用完整的路径,但完整的路径不是硬编码,而是运算出来的。*/
//InputStream ips = ReflectTest2.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
//InputStream ips = ReflectTest2.class.getResourceAsStream("resources/config.properties");
InputStream ips = ReflectTest2.class.getResourceAsStream("/cn/itcast/day1/resources/config.properties");