一、Eclipse的使用
•内容提示:Alt + /
•快速修复:Ctrl + 1
•导包:Ctrl + shift + O
•格式化代码块:ctrl + shift + F
•向前向后:Alt + 方向键
•添加注释 Ctrl+Shift+/
•除去注释 Ctrl+Shift+\
二、Junit使用
public class Demo4 { @Before public void before() { System.out.println("before"); } @Test public void testRun() { Person p = new Person(); p.run(); } @Test public void testEat() { Person p = new Person(); p.eat(); } @After public void after() { System.out.println("after"); } }
运行结果:
before
eating.
after
before
runing.
after
2、@BeforeClass、@Test、@AfterClass基本使用
public class Demo5 { @BeforeClass public void beforeClass() { System.out.println("beforeclass"); } @Test public void testRun() { Person p = new Person(); p.run(); } @Test public void testEat() { Person p = new Person(); p.eat(); } @AfterClass public void afterClass() { System.out.println("afterclass"); } }
运行结果:
before
eating.
runing.
after
三、JDK 5.0 新特性
1、静态导入,(了解即可,一般没人这么用)
import static java.lang.System.out; import static java.util.Arrays.sort; public class Demo1 { public static void main(String[] args) { out.print("main"); int[] a = new int[] { 6, 5, 3 }; sort(a); for (int i : a) out.print(i); } }
2、自动装箱/拆箱
public class Demo2 { public static void main(String[] args) { Integer i = 1;// 装箱 int j = i;// 拆箱 // 典型应用,list里只能装对象 List<Integer> list = new ArrayList<Integer>(); list.add(1);// 1被自动包装为Integer int k = list.get(0);// 自动拆箱 Iterator<Integer> it = list.iterator(); while (it.hasNext()) { int m = it.next();// 拆箱 } } }
3、增强for循环
Map for增强实例:
package cn.itcast.demo; import java.util.*; import java.util.Map.Entry; import org.junit.Test; public class Demo3 { @Test public void test3(){ Map map=new HashMap(); map.put("1", "aaa"); map.put("2", "bbb"); map.put("3", "ccc"); //传统方式1 Set set=map.keySet(); Iterator it=set.iterator(); while(it.hasNext()){ String key=(String)it.next(); String value=(String) map.get(key); System.out.println("key="+key+",value="+value); } //传统方式2 Set set2=map.entrySet(); Iterator it2=set2.iterator(); while(it2.hasNext()){ Map.Entry entry=(Entry)it2.next(); System.out.println("key="+entry.getKey()+",value="+entry.getValue()); } //增强for循环的1种方式,实际转为的set视图只存了key for(Object obj:map.keySet()){ String key2=(String)obj; String value2=(String)map.get(key2); System.out.println("key2="+key2+",value2="+value2); } //增强for循环的2种方式 for(Object obj:map.entrySet()){ Map.Entry entry3=(Entry) obj; String key3=(String) entry3.getKey(); String value3=(String) entry3.getValue(); System.out.println("key3="+key3+",value3="+value3); } //增强for循环需要注意的问题:只适合取数据,不适合更改 int arr[]={1,2,3}; for(int i: arr){ i=10; } System.out.println(arr[0]); // 1 List li=new ArrayList(); li.add("1"); for(Object obj : li){ obj="888"; } System.out.println(li.get(0));// 1 } }
4、可变参数
语法:
public void foo(int … args){}//三个点
public class Demo4 { @Test public void testSum(){ sum(1,2,3,4); int arr[]={5,6,7}; sum(arr); } public void sum(int ...nums){ int sum=0; for(int i:nums){ sum+=i; } System.out.println(sum); } //可变参数注意的问题 //public void aa(int ...nums,int s)//不可以,编译器晕逼了 //public void bb(int s ,int ...nums)//可以 @Test public void asListTest(){//api: public static <T> List<T> asList(T... a) List list=Arrays.asList("1","2","3"); System.out.println(list);//[1, 2, 3] String arr[]={"1","2","3","4"}; list=Arrays.asList(arr); System.out.println(list);//[1, 2, 3, 4] arr是对象数组 int nums[]={1,2,3,4,5}; list=Arrays.asList(nums); System.out.println(list);//[[I@120d62b],nums是一个对象 Integer nums2[]={1,2,3,4,5}; list=Arrays.asList(nums2); System.out.println(list);//[1, 2, 3, 4, 5] } }
5、枚举类
定义枚举的狗找函数、方法、字段:
/* * jdk5之前,只能这么定义 * class Grade{ * private Grade(){ } * public static final Grade A=new Grade(); * public static final Grade B=new Grade(); * public static final Grade C=new Grade(); * public static final Grade D=new Grade(); * public static final Grade E=new Grade(); * } */ enum Grade { A("100-90"), B("89-80"), C("79-70"), D("69-60"), E("59-0"); private String value; private Grade(String value){ this.value=value; } public String getValue(){ return this.value; } } public class Demo1 { @Test public void test() { print(Grade.B); } public void print(Grade g){ // A B C D E String value=g.getValue(); System.out.println(value); } }
带抽象方法的枚举:
enum Grade {// class A 100-90优 B 89-80良 C 79-70 一般D 69-60差 E 59-0不及格 //必须实现抽象方法 A("100-90"){ public String localeValue(){ return "优"; } }, B("89-80"){ public String localeValue(){ return "良"; } }, C("79-70"){ public String localeValue(){ return "一般"; } }; private String value; private Grade(String value){ this.value=value; } public String getValue(){ return this.value; } public abstract String localeValue(); } public class Demo1 { @Test public void test() { print(Grade.B); //89-80,良 } public void print(Grade g){ // A B C D E String value=g.getValue(); String value2=g.localeValue(); System.out.println(value+","+value2); } }
注意:
Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法.常用方法:
•name() //返回此枚举常量的名称,有毛用
•ordinal() //返回枚举常量的序数
•values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便.
6、反射
1、java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法.简而言之,动态获取类中信息就是反射.
2、java反射应用在很多java软件和框架中,例Tomcat,提供了处理请求和应答的方式,因为具体的处理动作不同,所以对外提供了接口,由开发者来实现具体的请求和应答处理.这个接口就是 servlet,开发者只要实现servlet接口,并配置相应的配置文件,对Tomcat来说就是在web.xml中配置servletname也就是类名,这样tomcat就能通过所谓的反射来加载该类的class文件,并获取类中的所有信息,从而实现开发者自定义的请求和应答处理方式.
3、类用来描述对象共性的信息,用来描述字节码文件的共性的类是Class类,该类提供获取字节码文件中的内容,包括类名称,属性和函数.反射依靠该类来完成.
4、获取字节码文件对象的三种方式:
1.Object类的getClass()方法,必须实例化类
2.任何数据类型都具备一个class静态属性(Objcet类的属性)来获取对于的Class对象.
3.通过给定的类的字符串名称就可以获取该类Class对象,更易扩展,该方法是forName(). 一般使用这种
例:String name="cn.itcast.Person"; Class c = Class.forName(name);
5、反射构造函数
import java.lang.reflect.Constructor; class Person{ String name; int age; public Person(){ System.out.println("wu can"); } public Person(String name,int age){ System.out.println("you can"); } } public class TestPerson { public static void main(String[] args) throws Exception{ Person p = new Person(); //根据字符串的名称查找该类的字节码文件,加载进内存,创建该字节码文件对象,创建对应的Person对象. String name="com.czbk.faceObjcet.Person"; Class clazz = Class.forName(name); //只能调用无参构造函数 Person p1 =(Person)clazz.newInstance(); //调用有参构造函数,getDeclaredConstructor可获取私有构造函数 Constructor c = clazz.getConstructor(String.class,int.class); Object o=c.newInstance("ww",26); } }
6、反射字段
public class TestPerson { public static void main(String[] args) throws Exception{ String str="com.czbk.faceObjcet.Person"; Class clazz = Class.forName(str); Object o = clazz.newInstance(); Field f = clazz.getField("name"); //只能获取公有属性,可获取父类 Object obj = f.get(o); Field f1 = clazz.getDeclaredField("age");//可获取私有属性,只限本类 f1.setAccessible(true); //对私有字段的访问取消权限检查,暴力访问 System.out.println(f1.get(o)); f1.setInt(o,22); System.out.println(o); } }
7、反射方法
public class TestPerson { public static void main(String[] args) throws Exception{ String str="com.czbk.faceObjcet.Person"; Class clazz = Class.forName(str); Object o = clazz.newInstance(); //调用无参方法 Method method=clazz.getMethod("toString", null); method.invoke(o, null); //调用有参方法 Method method1=clazz.getMethod("toString1", String.class); method1.invoke(o, "sss"); } }
8、主板运行实例(接口+配置)
public interface PCI { void run(); void close(); } public class SoundCard implements PCI{ public void run() { System.out.println("SoundCard Run"); } public void close() { System.out.println("SoundCard Close"); } } public class NetCard implements PCI{ public void run() { System.out.println("NetCard run"); } public void close(){ System.out.println("NettCard clase"); } } public class MainBoard { /*public void run(PCI p){ p.run(); } public void clase(PCI p){ p.close(); }*/ public static void main(String[] args) throws Exception { //这种方式每次增加新硬件时都需要修改主板源代码 /*SoundCard sc = new SoundCard(); MainBoard mb = new MainBoard(); mb.run(sc); mb.clase(sc);*/ //增加硬件无需修改MainBoard源代码,只要在配置文件中添加 Properties pt = new Properties(); FileInputStream is = new FileInputStream(new File("PCI.properties")); pt.load(is); for(int x=0;x<pt.size();x++){ String PCIName=pt.getProperty("pci"+x); Class clazz = Class.forName(PCIName); PCI p=(PCI)clazz.newInstance(); Method method = clazz.getMethod("run", null); method.invoke(p, null); } } }
7、内省(Introspector)
public class Demo1 { //得到bean所有属性 @Test public void test1() throws IntrospectionException{ BeanInfo info=Introspector.getBeanInfo(Person.class); //去掉Object里的属性(也就是class属性) BeanInfo info2=Introspector.getBeanInfo(Person.class,Object.class); PropertyDescriptor[] pds=info.getPropertyDescriptors(); for(PropertyDescriptor pd:pds){ System.out.println(pd.getName()); //ab age class name password } } //操纵bean的指定属性:age @Test public void test2() throws Exception{ Person p=new Person(); PropertyDescriptor pd=new PropertyDescriptor("age", Person.class); //得到属性的写方法,为属性赋值 Method method=pd.getWriteMethod(); method.invoke(p, 45); System.out.println(p.getAge());//45 //获取属性的值 method=pd.getReadMethod(); System.out.println(method.invoke(p, null));//45 } //高级内容,获取当前操作的属性的类型 @Test public void test3() throws Exception{ Person p=new Person(); PropertyDescriptor pd=new PropertyDescriptor("age", Person.class); //得到属性的写方法,为属性赋值 Method method=pd.getWriteMethod(); System.out.println(pd.getPropertyType());//int method.invoke(p, 45); System.out.println(p.getAge());//45 //获取属性的值 method=pd.getReadMethod(); System.out.println(method.invoke(p, null));//45 } }
2、内省—beanutils工具包
//使用beanUtils操纵bean的属性 ( 第三方) public class Demo1 { @Test public void test1() throws Exception{ Person p=new Person(); BeanUtils.setProperty(p, "age", 456); System.out.println(p.getAge());//456 } @Test public void test2() throws Exception{ String name="aaaa"; String age="123"; String password="pw"; Person p=new Person(); //支持8种基本类型自动转换 BeanUtils.setProperty(p, "name", name); BeanUtils.setProperty(p, "age", age); BeanUtils.setProperty(p, "password", password); System.out.println(p.getName());//aaaa System.out.println(p.getAge());//123 System.out.println(p.getPassword());//pw } @Test public void test3() throws Exception{ String birthday="1983-12-1"; //为了让日期赋值到bean的birthday属性上,给beanUtils注册一个日期转换器 //ConvertUtils.register(converter, clazz); ConvertUtils.register(new Converter(){ public Object convert(Class type, Object value) { if(value==null) return null; if(!(value instanceof String)){ throw new ConversionException("只支持String类型的转换"); } String str=(String)value; if(str.trim().equals("")) return null; SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd",Locale.US); try { return df.parse(str); } catch (ParseException e) { throw new RuntimeException(e); } } }, Date.class); Person p=new Person(); BeanUtils.setProperty(p, "birthday", birthday); System.out.println(p.getBirthday());//pw System.out.println("___"+BeanUtils.getProperty(p, "birthday")); } public void test5() throws Exception { Map map=new HashMap(); map.put("name", "aaa"); map.put("password", "123"); map.put("brithday", "1980-09-09"); ConvertUtils.register(new DateLocaleConverter(), Date.class); Person p=new Person(); //用map集合填充bean属性,map关键字和bean属性要一致 BeanUtils.populate(p, map); } }
8、泛型(Generic)
1、JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题,例:
ArrayList list = new ArrayList();
list.add("abc");
Integer num = (Integer) list.get(0); //运行时会出错,但编码时发现不了
ArrayList<String> list = new ArrayList<Object>(); 错,左右必须完全一致
ArrayList<Object> list = new ArrayList<String>(); 错
ArrayList<String> list = new ArrayList (); 对,可以一边没有
ArrayList list = new ArrayList<String>(); 对
3、自定义泛形——泛型方法
public static <T> void doxx(T t);
public class Demo1 { // 编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素. public <T> void reverse(T arr[]) { int startindex = 0; int endindex = arr.length - 1; while (true) { if (startindex >= endindex) break; T temp = arr[startindex]; arr[startindex] = arr[endindex]; arr[endindex] = temp; startindex++; endindex--; } } }
public static <K,V> V getValue(K key) { return map.get(key);}
public class GenericDao<T> {
private T field1;
public void save(T obj) {}
public T getId(int id) {}
}
//单例 public class ServiceFactory { private Properties serviceConfig = new Properties(); //单例的构造函数也只执行一次 private ServiceFactory(){ InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("service.properties"); try { serviceConfig.load(in); } catch (IOException e) { throw new RuntimeException(e); } } private static ServiceFactory instance = new ServiceFactory(); public static ServiceFactory getInstance(){ return instance; } public <T> T createService(Class<T> clazz){ //clazz.getName()拿到的带包名 String name = clazz.getSimpleName(); String className = serviceConfig.getProperty(name); try { T service = (T) Class.forName(className).newInstance(); return service; } catch (Exception e) { throw new RuntimeException(e); } } }
6、泛型的高级应用——通配符 略
9、Annotation(注解)
•@Override: 限定重写父类方法, 该注解只能用于方法
•@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
•@SuppressWarnings: 抑制编译器警告.
@Target(value={ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation1 { String name() default "zxx"; String password() default "123"; int age() default 12; Gender gender() default Gender.男;//枚举 MyAnnotation2 my2() default @MyAnnotation2(name="llll"); Class clazz() default String.class; String[] ss() default {"aa","bbb"}; int[] i() default {1,2}; }
6、提取 Annotation 信息
public class CategoryDao { private ComboPooledDataSource combods; @Injectpublic void setCombods(ComboPooledDataSource combods) { this.combods = combods; } }
@Retention(RetentionPolicy.RUNTIME) public @interface Inject { String driverClass() default "com.mysql.jdbc.Driver"; String jdbcUrl() default "jdbc:mysql://localhost:3306/bookstore"; String user() default "root"; String password() default "root"; }
7、注解在servlet 3.0中的使用案例,替代了在web.xml中的配置:
@WebFilter( urlPatterns = { "/ServletDemo1" }, initParams = { @WebInitParam(name = "charset", value = "UTF-8", description = "编码") }) public class FilterDemo1 implements Filter { FilterConfig fConfig=null; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { String charset = fConfig.getInitParameter("charset"); HttpServletRequest req = (HttpServletRequest)request; req.setCharacterEncoding(charset); chain.doFilter(request, response); } public void init(FilterConfig fConfig) { this.fConfig = fConfig; } public void destroy() { System.out.println("FilterDemo1 destroy!"); } }