黑马程序员--Java基础加强(高新技术)学习第一天
一、课程价值与目标介绍
二、eclipse及IDE开发工具介绍
eclipse和MyEclipse开发工具
三、eclipse工程管理与快捷键配置
1、编译器设置:
菜单Window/PreferencesàJava/compiler设置编译使用的JDK版本。
2、新建工作区
菜单File/Switch Workspce/Other…不同的开发人员创建自己的工作区配置自己的开发环境。
3、快捷键配置
菜单Window/ProferencesàGeneral/Keys。检查快捷键是否冲突。
四、eclipse视图管理与程序调试
1、设置断点
2、程序调试
3、菜单Window/Show View/…选择要显示的视图
五、配置eclipse的编译和运行环境
1、给工作区配置编译和运行环境
菜单Window/PreferencesàJava/Compiler配置编译使用的JDK版本。
菜单Window/PreferencesàJava/Intalled JREs配置Java运行环境。
2、给项目配置编译和运行环境
选中项目右击菜单Run As/Run Configurations…配置Java运行环境。
3、更改workspace的运行环境会同时修改各个项目的运行环境。
六、在eclipse中配置Java模板代码
菜单Window/PreferenceàJava/Editor/Templates进行配置。
七、在eclipse中导入已有的工程
菜单File/ImportàGeneral/Existing Projects into Workspace
八、静态导入与编译器语法设置
例如:int max=Math.max(3, 6);
可以静态导入import static java.lang.Math.*;后使用int max= max(3, 6);
或者
静态导入import static java.lang.Math.max;后使用int max= max(3, 6);
九、可变参数与Overload相关面试题分析
1、override和overload的区别:
override(重写,覆盖)
1、方法名、参数、返回值相同。
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final不能被重写。
overload(重载,过载)
1、参数类型、个数、顺序至少有一个不相同。
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。
方法的重写(Overriding)和重载(Overloading)是Java多态性的不同表现。
重写(Overriding)是父类与子类之间多态性的一种表现,而重载(Overloading)是一个类中多态性的一种表现。
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)
。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了.
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型或有不同
的参数次序,则称为方法的重载(Overloading)。不能通过访问权限、返回类型、抛出的异常进行重载.
1. Override 特点
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
2.Overload 特点
1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int, float), 但是不能为fun(int, int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。
2、可变参数的使用:
public class VariableParameter
{
public static void main(String[] args)
{
System.out.println(add(1,2));
System.out.println(add(1,2,3));
System.out.println(add(1,2,3,4));
}
public static int add(int... args)
{
int count=0;
for(int i:args)
count+=i;
return count;
}
}
十、Java5的增强for循环:
1、语法:
for(type 变量名:集合变量名){}
2、注意事项:
(1)迭代变量必须在()中定义。
(2)集合变量可以使数组或是实现Iterable接口的集合类。
十一、基本数据的自动拆箱及享元设置模式(Flyweight Pattern)
public class AutoBox
{
public static void main(String[] args)
{
Integer i=10;//装箱
i=i+10;//i拆箱后与10相加,和再装箱成Integer类型。
Integer i1=127;
Integer i2=127;
Integer i3=128;
Integer i4=128;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//false
Integer i5=Integer.valueOf(127);//这不是装箱
Integer i6=Integer.valueOf(127);
Integer i7=Integer.valueOf(128);
Integer i8=Integer.valueOf(128);
System.out.println(i5==i6);//true
System.out.println(i7==i8);//false
}
}
十二、枚举作用的介绍
十三、用普通类模拟枚举的实现原理
1、 私有的构造方法。
2、每个元素分别用一个公有的静态成员变量表示。
3、可以有若干公有方法或抽象方法。
(1)使用非抽象类模拟枚举
public class Week
{
private int day;
private Week(int day)
{
this.day=day;
}
public static final Week Sunday=new Week(0);
public static final Week Monday=new Week(1);
public static final Week Tuesday=new Week(2);
public static final Week Wednesday=new Week(3);
public static final Week Thursday=new Week(4);
public static final Week Friday=new Week(5);
public static final Week Saturday=new Week(6);
public Week nextDay()
{
return new Week((this.day+1)%7);
}
public String toString()
{
switch(this.day)
{
case 0:
return "Sunday";
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
default:
return "I don't know what day it is today";
}
}
}
(2)使用抽象类模拟枚举
public abstract class AbstractWeekDay
{
private AbstractWeekDay(){}
public static final AbstractWeekDay SUNDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return MONDAY;
}
};
public static final AbstractWeekDay MONDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return TUESDAY;
}
};
public static final AbstractWeekDay TUESDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return WEDNESDAY;
}
};
public static final AbstractWeekDay WEDNESDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return THURSDAY;
}
};
public static final AbstractWeekDay THURSDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return FRIDAY;
}
};
public static final AbstractWeekDay FRIDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return SATURDAY;
}
};
public static final AbstractWeekDay SATURDAY =new AbstractWeekDay()
{
public AbstractWeekDay nextDay()
{
return SUNDAY;
}
};
public abstract AbstractWeekDay nextDay();
public String toString()
{
if(this==SUNDAY)
return "SUNDAY";
else if(this==MONDAY)
return "MONDAY";
else if(this==TUESDAY)
return "TUESDAY";
else if(this==WEDNESDAY)
return "WEDNESDAY";
else if(this==THURSDAY)
return "THURSDAY";
else if(this==FRIDAY)
return "FRIDAY";
else if(this==SATURDAY)
return "SATURDAY";
else
return "I don't know what day it is today";
}
}
十四、Java5枚举的基本应用
1、一个星期的实例
public class EnumDemo
{
public static void main(String[] args)
{
WeekDay w=WeekDay.MONDAY;
System.out.println(w);
System.out.println(w.compareTo(WeekDay.SATURDAY));
System.out.println(w.equals(WeekDay.MONDAY));
System.out.println(w.name());
System.out.println(w.ordinal());
System.out.println(w.toString());
for(WeekDay wd:WeekDay.values())
System.out.println(wd);
}
public enum WeekDay
{
SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}
}
2、枚举的常用方法
十五、实现带有构造方法的枚举
1、元素列表要放在最前面。
2、构造函数是私有的。
3、带有参数的构造函数。枚举元素如MONDAY和MONDAY()都是调用的默认构造函数。
4、枚举只有一个成员时,就可以作为一个单例是实现方法。
十六、实现带有抽象方法的枚举:交通灯实例
public class EnumTest
{
public static void main(String[] args)
{
trafficLamp l=trafficLamp.GREEN;
System.out.println(l.nextLamp());
}
public enum trafficLamp
{
RED(30)
{
public trafficLamp nextLamp()
{
return GREEN;
}
},
GREEN(30)
{
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;
}
public String toString()
{
switch(this)
{
case RED:
return "red";
case GREEN:
return "green";
case YELLOW:
return "yellow";
}
return "";
}
}
}
十七、透彻分析反射的基础(Class类)
1、Java程序中的多个Java类属于同一个事物,描述这类事物的Java类名就是Class。
2、获取字节码的三种方法:
(1)类.class
(2)对象.getClass()
(3)Class.forName(数据类型)
3、9个预定义Class实例对象:8个基本数据类型和void。
4、Class类方法:
(1)isPrimitive()是否基本数据类型。
(2)int.class==Integer.TYPE;包装的基本数据类型的字节码。
(3)数组的字节码:int[].class.isArray()是否数组。
十八、理解反射的概念
反射就是把Java类中的各个成分映射成相应的Java类,java.lang.reflect。
十九、构造方法的反射应用,Constructor类
Constructor类代表某个类中的一个构造方法。实例如下:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ConstructorReflectDemo
{
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
{
//打印String类所有的构造方法
Constructor[] cons=String.class.getConstructors();
for(Constructor con:cons)
System.out.println(con);
//打印String类中参数为StringBuffer类的构造方法
Constructor con=String.class.getConstructor(StringBuffer.class);
System.out.println(con);
//使用反射得到的构造函数创建String对象
String str=(String)con.newInstance(new StringBuffer("abc"));
System.out.println(str);
System.out.println(str.charAt(2));
}
}
二十、成员变量的反射,Field类
public class FieldReflectDemo
{
public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
{
ReflectPoint pt1=new ReflectPoint(4,5);
//获取pt1实例的类的所有公有的字段
Field[] fields=pt1.getClass().getFields();
for(Field f:fields)
System.out.println(f);
//获取pt1实例的类的所有的字段,包括私有成员
Field[] fields2=pt1.getClass().getDeclaredFields();
for(Field f:fields2)
System.out.println(f);
//获取pt1中公有成员变量y的值
Field fieldY=pt1.getClass().getField("y");
System.out.println(fieldY.get(pt1));
//获取pt1中私有成员变量x的值
Field fieldX=pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);//暴力反射
System.out.println(fieldX.get(pt1));
//获取pt1实例的类中String类型的成员变量
Field[] fields3=pt1.getClass().getDeclaredFields();
for(Field f:fields3)
{
if(f.getType()==String.class)
System.out.println(f);
}
//把pt1中所有String类的成员变量的值中的b改成a
Field[] fields4=pt1.getClass().getDeclaredFields();
for(Field f:fields4)
{
if(f.getType()==String.class)
{
String oldValue=(String)f.get(pt1);
String newValue=oldValue.replace('b', 'a');
f.set(pt1, newValue);
}
}
System.out.println(pt1);
}
}
二十一、成员变量反射的综合实例:修改成员变量的值(如上)
二十二、成员方法的反射,Method类
如果传递给Method对象的invoke()方法的第一个参数为null,说明该成员对应的是一个静态方法。
示例如下:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodReflectDemo
{
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
//str1.charAt(1);
String str1="abc";
Method methodCharAt=String.class.getMethod("charAt", int.class);
//System.out.println(methodCharAt);
System.out.println(methodCharAt.invoke(str1, 1));
//打印String类中所有成员方法
Method[] methods=String.class.getMethods();
for(Method m:methods)
System.out.println(m);
}
}
二十三、对接受数组参数的成员方法进行反射
写一个程序,这个程序能够根据用户提供的类名去执行该类中的main方法,配置程序运行参数为cn.itcast.day01.ArgsTest:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ArgumentReflectDemo
{
public static void main(String[] args) throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
String[] strs={"abc","aaa","bbb"};
//常用方法
ArgsTest.main(strs);
//反射 args传递的参数是:cn.itcast.day01.ArgsTest
String startingClassName=args[0];
Method m=Class.forName(startingClassName).getMethod("main", String[].class);
//m.invoke(null, new String[]{"aaa","bbb","ccc","ddd"}); IllegalArgumentException异常:wrong number of arguments
m.invoke(null, (Object)new String[]{"aaa","bbb","ccc","ddd"});
//或者
m.invoke(null, new Object[]{new String[]{"aaa","bbb","ccc","ddd"}});
}
}
class ArgsTest
{
public static void main(String[] args)
{
for(String s:args)
{
System.out.println(s);
}
}
}
二十四、数组与Objec的关系及其反射类型
(1)具有相同位数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
(2)代表数组的Class实例对象的getSuperClass()方法返回父类为Object类对应的Class。
(3)基本数据类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;
非基本类型的一维数组既可以当做Object类型使用,又可以当做Object[]类型使用。
(4)java.lang.reflect.Array.asList()方法处理int[]和String[]时不同。
(5)java.lang.reflect.Array工具类用于完成数组的反射操作。
实例如下:
import java.lang.reflect.Array;
public class ArrayReflectDemo
{
public static void main(String[] args)
{
int[] arr1=new int[2];
int[] arr2=new int[5];
int[][] arr3=new int[2][3];
String[] arr4=new String[2];
System.out.println(arr1.getClass());//class [I
System.out.println(arr2.getClass());//class [I
System.out.println(arr3.getClass());//class [[I
System.out.println(arr4.getClass());//class [Ljava.lang.String;
//获取数组超类的Class,都是java.lang.Object
System.out.println(arr1.getClass().getSuperclass());//class java.lang.Object
System.out.println(arr2.getClass().getSuperclass());
System.out.println(arr3.getClass().getSuperclass());
System.out.println(arr4.getClass().getSuperclass());
//将数组转换成Object
Object obj1=arr1;//基本数据类型的一位数组可以当做Object类型使用
Object obj2=arr3;
Object obj3=arr4;
//Object[] obj4=arr1;//基本数据类型的一维数组不能当做Object[]类型使用
Object[] obj5=arr3;
Object[] obj6=arr4;//非基本数据类型的一维数组既可以当做Object类型使用,又可以当做Object[]类型使用
printObject(obj1);
printObject(obj2);
printObject(obj3);
}
private static void printObject(Object obj)
{
Class cls=obj.getClass();
if(cls.isArray())
{
int len=Array.getLength(obj);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(obj, i));
}
}
else
{
System.out.println(obj);
}
}
}