按张老师高新技术视频所做笔记。
jdk1.5新特性:泛型,for-each循环,自动装包/拆包,枚举,可变参数,静态导入。使用这些特性有助于我们编写更加清晰,精悍,安全的代码。
jdk1.6新特性:
- 新增加了两个类:Desktop和SystemTray。
- 使用JAXB2来实现对象与XML之间的映射。
- 理解StAX。
- 使用Compiler API。
- 轻量级Http Server API。
- 插入式注解处理API(Pluggable Annotation Processing API)。
- 用Console开发控制台程序。
- 对脚本语言的支持如: ruby, groovy, javascript。
- Common Annotations。
workspace(工作台)和project(项目):工作台可以定义整体的一些偏好之类的,项目自己可以定义一些特有的风格(类似于继承中的父类子类关系)。
perspective(透视图)和view(视图):视图就是开发界面的单个小窗口,透视图就是几个小窗口的搭配。
例:java视图,断点调试视图。也可以自己选择所要显示视图:window > show View 选择。
javac(java compiler)和java:高版java能运行低版javac,低版java不能运行高版javac。
配置快捷键:例:配置 alt + / 为内容助理(content assist)步骤: window > preferences > general > keys > 将content assist设置为Alt + /
配置模板(templates):例 :配置tryf 为try{}finally{}模板 步骤:window > preferences > java > editor > templates > new > name中输入tryf pattern中输入try{}finally{}
前面的花括号insert variable(插入变量) 选择${line_selection}(选中行) 后面花括号选择${cursor}(光标)
前面的花括号insert variable(插入变量) 选择${line_selection}(选中行) 后面花括号选择${cursor}(光标)
导入项目:例:file > import > general > existing project into workspace(已有项目) 或者 file system (文件系统,需要选择现项目的文件夹作为目标)
如果导入的项目jar包路径和自己的jar包路径不一样,要build path删除原路径,改为自己正确的路径。
jdk1.5新特性可变参数:参数不用传数组而且避免了很多重载。
代码演示:
public class VariableParameter {
public static void main(String[] args) {
System.out.println(add(2,3,6,4));
System.out.println(add(2,3));
}
static int add(int x, int... args){
int sum = x;
for(int arg : args){
sum += arg;
}
return sum;
}
}
增强for循环:
代码演示:
public class EnhanceFor {
public static void main(String[] args) {
int[] a = {2,5,3,5,4,23,54};
//增强for循环语法:for(Type 变量名 : 集合名)Type前可加修饰,如:final,
//遍历的对象须实现Iterator接口
for(int i : a){
System.out.print(i + "\t");
}
}
}
基本数据类型的自动拆箱装箱:
代码演示:
public class AutoBox {
public static void main(String[] args) {
Integer a1 = 13;
Integer a2 = 13;
Integer a3 = Integer.valueOf(13);
Integer b1 = 130;
Integer b2 = 130;
Integer b3 = Integer.valueOf(130);
System.out.println(a1 == a2 && a1 == a3);//结果是true
System.out.println(b1 == b2 || b1 == b3);//结果是false
}
}
首先对于:System.out.println(a1 == a2);//结果是true,分析:a1和a2的数值都小于一个字节,
所以在第一次创建 Integer对象也就是a1时就会在对象缓存池中存有一个值为13的Integer的对象
当再次创建值为13的Integer的对象也就是a2时,就会直接将缓存池中13的引用传递给a2
所以a1和a2指向的对象地址是同一个,所以打印的结果是true
对于:System.out.println(b1 == b2);//结果是false
分析:首先要知道,当创建的对象的数值大于一个字节要表达的数时,就不会再数据缓存池中
缓存该对象,而b1和b2的值是130大于128,所以b1和b2创建的是两个完全不同的对象,所以两者不等
打印结果为false 。
享元模式:很多小的对象,有很多属性相同,把他们作为一个对象,那些不同的属性作为方法的参数,称之为外部状态,相同的属性称之为内部状态。
枚举:
编译时就判断赋值是否合法,只能赋规定好的值
模拟简单枚举
public abstract class WeekDay1 {
public static void main(String[] args) {
WeekDay1 weekDay1 = WeekDay1.SUN;
System.out.println(weekDay1.nextDay());
}
private WeekDay1(){}
//不可变的静态本类成员变量由子类实例化(内部类),重写父类的抽象方法
//内部类平行于成员,有四种修饰符
public final static WeekDay1 SUN = new WeekDay1(){
@Override
public WeekDay1 nextDay() {
// TODO Auto-generated method stub
return MON;
}
};
public final static WeekDay1 MON = new WeekDay1(){
@Override
public WeekDay1 nextDay() {
// TODO Auto-generated method stub
return SUN;
}
};
//抽象方法
public abstract WeekDay1 nextDay();
//覆盖toString
public String toString(){
return this == SUN ? "SUN" : "MON";
}
}
枚举代码:
public class EnumTest {
public static void main(String[] args) {
WeekDay weekDay = WeekDay.星期三;
System.out.println(weekDay);
System.out.println(weekDay.ordinal());
System.out.println(weekDay.name());
System.out.println(weekDay.getClass());
System.out.println(WeekDay.valueOf("星期一").ordinal());
System.out.print("++++遍历+++++长度>>");
//静态方法,values()返回本类对象数组WeekDay[],valueOf(String arg)将arg转为枚举类
System.out.println(WeekDay.values().length);
for(WeekDay w : WeekDay.values()){
System.out.println(w);
}
}
//枚举就是一个类,枚举的成员就是这个类的实际对象;
//枚举的元素列表必须在最前面,后面要是有内容列表后必须有“;”
//无括号相当于空参数,默认构造函数
enum WeekDay{
星期一,星期二,星期三,星期四(),星期五,星期六,星期天(7);
WeekDay(){
System.out.println("first");
}
WeekDay(int i){
System.out.println("second");
}
}
//交通灯枚举,调用带参构造创建枚举成员,内部类实现抽象方法
public enum TrafficLamp{
RED(30){
public TrafficLamp nextTrafficLamp(){
return GREEN;
}
},
GREEN(40){
public TrafficLamp nextTrafficLamp(){
return YELLOW;
}
},
YELLOW(5){
public TrafficLamp nextTrafficLamp(){
return RED;
}
};
public abstract TrafficLamp nextTrafficLamp();
private int time;
private TrafficLamp(int time){
this.time = time;
}
}
}
枚举可以简化创建单例模式,因为默认私有构造方法。
反射:就是把java中的各种成分隐射成相应的java类
Class类的对象对应字节码文件,字节码不在内存则加载进内存,已经加载进内存的直接指向,所以同一类字节码文件是同一份,可以"=="进行比较。三种方式获得字节码文件:对象.getClass(); 类.class; Class.forName(String arg);最常用第三种代码(注释):package cn.itcast.day1; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Date; public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { //得到字节码 Class c1 = Class.forName("java.util.Date"); //得到字节码 Class c2 = Date.class; //得到字节码 Class c3 = new Date().getClass(); System.out.println(c1); System.out.println(c2); System.out.println(c3); //“==”比较同类的字节码文件是否是同一份文件 System.out.println(c1 == c2 && c1 == c3); System.out.println("=======Date类的方法======"); Method[] ms = c1.getMethods(); for(Method m : ms){ System.out.println(m); } System.out.println("=======Calendar类的方法======"); Class c10 = Class.forName("java.lang.Calendar"); Method[] ms10 = c10.getMethods(); for(Method m : ms10){ System.out.println(m); } System.out.println("========================"); Class pc = Class.forName("cn.itcast.day1.Person"); // pc.getClass(); // Class cc = Class.class; for(Method m : pc.getMethods()){ System.out.println(m); } //八基本类型 和void是原始类型 isPrimitive判断为true //只要在源程序中出现的类型,都有各自的Class类实例对象,如int、void、int[] System.out.println("String是否是基本类型? " + String.class.isPrimitive()); System.out.println("int是否是基本类型? " + int.class.isPrimitive()); System.out.println("void是否是基本类型? " + void.class.isPrimitive()); System.out.println("Integer是否是基本类型? " + Integer.class.isPrimitive()); //包装类的常量TYPE代表所包装的类的字节码 System.out.println("包装类的常量TYPE代表所包装的类的字节码?" + (int.class == Integer.TYPE)); System.out.println("包装类的常量TYPE代表所包装的类的字节码?" + (double.class == Double.TYPE)); System.out.println("包装类的常量TYPE代表所包装的类的字节码?" + (boolean.class == Boolean.TYPE)); System.out.println("数组是否原始类型? " + int[].class.isPrimitive()); System.out.println("此类型是否是数组? " + int[].class.isArray()); System.out.println("=============="); //Constructors获得所有构造方法返回数组 Constructor[] cc = String.class.getConstructors(); for(Constructor c : cc){ System.out.println(c); // System.out.println(new StringBuffer(c.toString()).substring(new StringBuffer(c.toString()).lastIndexOf(".") + 1)); } //得到参数为String类型的构造方法 System.out.println(String.class.getConstructor(String.class)); //加载类,得到为参数的StringBuffer的构造方法,传递参数new StringBuffer("jgjk")创建字符串对象s2. String s2 = (String)Class.forName("java.lang.String").getConstructor(StringBuffer.class).newInstance(new StringBuffer("jgjk")); System.out.println(s2); //以下两句效果相同,第一种为得到无参构造方法再创建实例的简便方式 String str = (String)String.class.newInstance(); String str1 = (String)String.class.getConstructor().newInstance(); //Field属性类 ReflectPoint rp1 = new ReflectPoint(3,5); //得到该类的b属性f1(该类的字节码.getField(字段)) Field f1 = rp1.getClass().getField("b"); //得到具体对象的具体属性值 int b = (Integer) f1.get(rp1); System.out.println(b); //getDeclaredField可以得到该类的私有属性 Field f2 = rp1.getClass().getDeclaredField("a"); //暴力反射,设置对象的私有属性可以访问,取出私有变量值 f2.setAccessible(true); int a = f2.getInt(rp1); System.out.println(a); System.out.println("==========Method=========="); //Method String str2 = "abc"; Method methodCharAt = String.class.getMethod("charAt", int.class); Object ch = methodCharAt.invoke(str2, 1); System.out.println(ch); System.out.println("=========数组============"); int[] ar1 = new int[]{1,4,2,4,3}; int[] ar2 = new int[3]; int[][] ar3 = new int[2][]; String[] ar4 = new String[]{"1","2","3"}; System.out.println(ar1.getClass() == ar2.getClass()); System.out.println(ar1 == ar2); System.out.println(ar1.getClass().getName()); System.out.println(ar3.getClass().getName()); System.out.println(ar4.getClass().getName()); System.out.println(ar1.getClass().equals(ar3.getClass())); System.out.println(ar1.getClass().getSuperclass().getName()); // System.out.println(ar1.getClass() == ar4.getClass()); System.out.println(Arrays.asList(ar4)); printObj(ar1); } private static void printObj(Object obj) { if(obj.getClass().isArray()){ int len = Array.getLength(obj); for(int i = 0; i < len; i ++){ System.out.println(Array.get(obj, i)); } } } } class Person{}
反射的应用:package cn.itcast.day1; import java.lang.reflect.Field; /** * 随便给个对象,把对象中字符串成员变量的a值改为b * @author xdy * */ public class Practice1 { public static void main(String[] args) throws Exception { //练习类加载器,默认构造函数实例化类 // Point p = (Point) Class.forName("cn.itcast.day1.Point").newInstance(); Point p = new Point(); changeStringValue(p); } private static void changeStringValue(Object obj) throws Exception { //通过该类的字节码得到该类的属性数组 Field[] fs = obj.getClass().getFields(); //加强for循环遍历 for(Field f : fs){ //判断属性类型 if(f.getType() == String.class){ //获得传入对象的对应属性值 String oldStr = (String) f.get(obj); //替换 String newStr = oldStr.replace('a', 'b'); //设置对象的属性值 f.set(obj, newStr); } } //打印 System.out.println(obj); } } class Point{ public String s1 = "base"; public String s2 = "itcast"; public String s3 = "ball"; @Override public String toString(){ return s1 + ":" + s2 + ":" + s3; } }
package cn.itcast.day1; import java.lang.reflect.Method; import java.util.Arrays; /** * * 利用反射技术调用其他类的main方法 * @author xdy * */ public class Practice2 { public static void main(String[] args) throws Exception { String name = args[0]; Method mainMethod = Class.forName(name).getMethod("main", String[].class); mainMethod.invoke(null, (Object)new String[]{"11","987"}); int[] a = {1,3,2,5,90}; String[] s = {"1","3","2","5","90"}; System.out.println(Arrays.asList(a)); System.out.println(Arrays.asList(s)); // // inVokeMain(args); // System.out.println(args.length); // for(String arg : args){ // System.out.println(arg); // } // Invokem.main(new String[] {"12","ad","adww"}); } public static void inVokeMain(Object args) throws Exception{ Method m = ReflectTest.class.getMethod("main", String[].class); m.invoke(null, args); } } class Invokem{ public static void main(String[] args) { for(String arg : args){ System.out.print(arg + "\t"); } } }