1.java基础加强

来源:互联网 发布:linux xampp使用教程 编辑:程序博客网 时间:2024/06/03 16:02

1.当eclipse项目改变了编译配置(项目右键属性Properties->Java Compiler),用了高版本的编译器编译,则用低版本的JVM运行会报错,弹窗JVM启动警告Could not find the main class.Program will exit,报class文件的版本号错误java.lang.UnsupportedClassVersionError:Bad version number in .class file。
解决办法:
降低编译器版本。
升高运行版本。(项目右键属性Properties->Java Build Path->Libraries添加高版本jre)

2.断点:

F5:step into 跳入F6:step over 跳过F7:step return跳出drop to frame:跳到当前方法的第一行resume:跳到下一个断点(如果没有下一个,则运行完整个程序)右键watch:观察变量或表达式的值断点注意的问题:1.断点调试完成后,要在breakpoints视图中清除所有断点2.断点调试完成后,一定要记得结束运行断点的jvm

3.常用快捷键:

ctrl + shift + L : 查看所有快捷键alt + / : 内容助理ctrl + 1: 快速修复ctrl + shift +o : 导包ctrl + shift +F : 格式化代码块ctrl + 左键    /  F3:查看代码中存在方法,类的源代码ctrl + shirt + T :查看指定类的源代码Alt + 左/右:查看源代码的时候,回到上一步/下一步ctrl + shift + / :  添加注释  /**/ ctrl + shift + \:   除去注释  /**/ F2 :查看方法说明重置透视图(windows save/reset)ctrl + shift + X :大写ctrl + shift + Y :小写ctrl + alt + 向上/下键:复制行alt + 向上/下键:移动行ctrl + T : 查看继承关系ctrl +m : 窗口最大化/还原ctrl +f :查找替换ctrl + shift + L 查看所有快捷键

4.junit测试框架:在测试方法前加@Test

1.每个测试方法之前都运行:(常用)@Before + 方法前: 初始化资源@After  + 方法前: 释放资源2.类加载的时候运行,只运行一次: 方法必须设置静态static@BeforeClass + 方法前:作用同上@AfterClass + 方法前:3.断言类:判断返回值import static org.junit.Assert.*; assertEquals("返回值错误!","2", p.run());

5.JDK1.5新特性:

1.静态导入:导入类的静态成员,方便程序简化书写。
2.自动装箱拆箱:

int num = 4;num = num + 5;Integer i =4;  //等效,Integer i = new Integer(4);  自动装箱,就是简化书写。             //自动装箱和不同赋值相比,多了一个空null。            //所以要先判断是否为null。因为空类型在拆箱的时候会报空指针异常。i = i + 6;   //等效i = new Integer(i.intValue() + 6); 自动装箱,拆箱(i.intValue())。show(55);public static void show(Object a){  //Object a = new Ingeter(55);  装箱,多态}

面试:自定装箱,如果装箱的是一个字节,那么该数据会被共享,不会重新开辟空间。

Integer a = new Integer(127);Integer b = new Integer(127);System.out.println(a==b);  //falseSystem.out.println(a.equals(b));  //trueInteger x = 127;Integer y = 127;System.out.println(x==y);   //true, 自定装箱,如果装箱的是一个字节,那么该数据会被共享,不会重新开辟空间。System.out.println(x.equals(y));  //true
public class Demo1 {    public static void main(String[] args) {        List<Integer> list = new ArrayList<Integer>();        list.add(127);   //装箱        list.add(127);        Iterator<Integer> it = list.iterator();        while(it.hasNext()){            System.out.println(it.next()==it.next());   //true,超过一个字节就是false        }    }}

3.增强for循环
JDK1.5给Collection接口找了个父接口Iterable,实现这个接口允许对象成为 “foreach” 语句的目标。

foreach语句:底层还是实现的迭代。格式:for(类型 变量: Collection集合|数组){}
传统for和高级for的区别:foreach局限性:必须有遍历的目标(数组或Collection单列集合),一般只用于遍历,不会对元素进行过多的操作。是用来简化书写的。传统for循环相对foreach的优势:可以定义控制循环的条件和增量。使用场景:对数组的遍历如果仅仅是获取数组中的元素,可以使用foerach。如果要对数组的角标进行操作建议使用传统for。对于map集合,不能直接使用foreach遍历。但是可以将map转换成单列的set,就可以用了。例子:    public static void main(String[] args) {        Map<String,Integer> map = new HashMap<String,Integer>();        map.put("小米", 2000);        map.put("苹果", 5000);        map.put("三星", 4000);//entrySet:             Set<Map.Entry<String, Integer>> entrySet = map.entrySet(); //map变成set集合        for (Map.Entry<String, Integer> entry : entrySet) {                 //foreach遍历            System.out.println(entry.getKey() + ":" +entry.getValue());        }//keySet:for(String key : map.keySet()){    Integer value = map.get(key);    System.out.println(key + ": " + value);}//传统迭代:             Iterator<Map.Entry<String,Integer>> it= map.entrySet().iterator();        while(it.hasNext()){            Map.Entry<String, Integer> me = it.next();            System.out.println(me.getKey() + ":" + me.getValue());        }    }

4.可变参数:int …

内部执行的动作:创建并将参数封装成数组。其实就是一个数组,但是接收的是数组的元素。 自动将这些元素封装成数组。简化了调用者的书写。注意事项:可变参数类型必须定义在参数列表的结尾处。
//求多个正数的和public static void main(String[] args){    int sum = add(2,5,6,6);    System.out.println("sum= " + sum);    int sum1 = add(2,5,6);    System.out.println("sum1= " + sum1);}public static int add(int... arr){  //int... 和int[]等效,简化书写。调用传参的时候不需要建立数组,直接传值。    int sum = 0;    for(int i:arr)        sum+=i;    return sum;}

5.枚举类:

1.作用:一些程序在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,jdk5以前用自定义类来解决,jdk5以后可以直接采用枚举类解决。2.enum关键字定义一个枚举类。3.一个枚举也可以用构造函数,字段,和方法。4.示例:public class Demo1 {    public void test(){        print(Grade.B);         }    public void print(Grade g){   //A B C D E           }   }/*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{      //class    A,B,C,D,E;    //Object}5.定义枚举的构造方法,方法,和字段: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);    }   }/*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();}*///等效于//如何定义枚举的构造方法,方法,和字段去封装更对的信息enum Grade{       //class        A 100-90 B 89-80 C 79-70    A("100-90"),B("89-80"),C("79-70");    //Object    private String value;     //封装每个对象对应的分数    private Grade(String value){        this.value = value;    }    public String getValue(){        return this.value;    }}
6.带抽象方法的枚举:public class Demo1 {    @Test    public void test(){        print(Grade.B);         }    public void print(Grade g){   //A B C D E               String value = g.getValue();        String lValue = g.localeValue();        System.out.println(value + "("+lValue+")");    }   }//带抽象方法的枚举enum Grade{       //class        A 100-90 优     B 89-80良     C 79-70一般    A("100-90"){        public String localeValue(){            return "优";        }    }    ,B("89-80"){        public String localeValue(){            return "良";        }    }    ,C("79-70"){    //Object        public String localeValue(){            return "一般";        }    };    private String value;     //封装每个对象对应的分数    private Grade(String value){        this.value = value;    }    public String getValue(){        return this.value;    }    public abstract String localeValue();}
7.枚举的常用方法和其他细节:①枚举类也是一种特殊形式的Java类②枚举类中声明的每一个枚举值代表枚举类的一个示例对象。③与java中的普通类一样,在声明枚举类时,也可以声明属性,方法和构造函数,但枚举类的构造函数必须为私有的。④枚举类也可以实现接口,或继承抽象类。⑤JDK5中还扩展了switch语句,它除了可以接收int,byte,cher,short外,还可以接收一个枚举类型。⑥若枚举类只有一个枚举值,则可以当作单态设计模式使用。Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:name()返回此枚举常量的名称,在其枚举声明中对其进行声明。ordinal()返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。 大多数程序员不会使用此方法。它被设计用于复杂的基于枚举的数据结构,比如 EnumSet 和 EnumMap。 valueOf(Class enumClass, String name) 返回带指定名称的指定枚举类型的枚举常量。如果不存在字符串对应的枚举,就会报错。用于判断用户提交的字符串是否是枚举。values()此方法虽然在在JDK文档中查找不到,但每个枚举类都具有该方法,它用于遍历枚举的所有枚举值。//测试枚举的常用方法    @Test    public void test2(){        System.out.println(Grade.A.name());        System.out.println(Grade.A.ordinal());        String str = "B";//      Grade g =  Grade.valueOf(Grade.class,str);        Grade g =  Grade.valueOf(str);              System.out.println(g);        Grade gs[] = Grade.values();        for(Grade gg : gs){            System.out.print(gg);        }    }

6.反射技术:

1.一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。2.什么情况下需要加载类,并解剖出类的各个组成部分:

加载类:

1.java中有一个Class类用于代表某一个类的字节码。2.Class类既然代表某个类的字节码,它当然就是要提供加载某个类字节码的方法:forName()。forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。static Class<?> forName(String name, boolean initialize, ClassLoader loader)          使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。 3.另外两种得到class对象的方式:类名.class对象.getClass()public class Demo2 {    /*            反射:加载类,获得类是字节码     */    public static void main(String[] args) throws ClassNotFoundException {        //1.        Class clazz =  Class.forName("/myday01/src/cn/itcast/eclipse/Person");        //2.        Class clazz1 = new Person().getClass();        //3.        Class clazz2 = Person.class;    }}

解剖类:

1.Class对象提供了如下常用方法:①返回public的成员Constructor<T> getConstructor(Class<?>... parameterTypes)           返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 Method getMethod(String name, Class<?>... parameterTypes)           返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 Field getField(String name)           返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。         ②返回类声明的所有成员Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)           返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 Method getDeclaredMethod(String name, Class<?>... parameterTypes)           返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 Field getDeclaredField(String name)           返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 2.这些方法分别用于从类中解剖出构造函数,方法和成员变量。解剖出的成员分别用Constructor,Method,Field对象表示。3.如果你是一个框架的设计者,解剖出这些成员后你会干什么:使用。

反射类的构造函数:
利用Constructor创建对象

1.Constructor类提供了如下方法,用于创建类的对象。T newInstance(Object... initargs)         使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 initargs用于指定构造函数接收的参数。2.练习:反射类无参,有参,私有的构造函数,创建类的对象。另:class对象中也有一个newInstance()方法,用于创建类的对象。这样开发人员可以避免每次都需要反射Constructor类以创建对象。但是需要注意的是:class.newInstance()方法内部是反射类无参的构造函数创建的对象,所以用此种方式创建类对象时,类必须有一个无参的构造函数。 示例://反射类的构造函数,创建类的对象public class Demo2 {    //反射构造函数:public Person()    @Test    public void test1() throws Exception{        Class clazz =  Class.forName("cn.itcast.eclipse.Person");               Constructor c =  clazz.getConstructor(null);        Person p = (Person) c.newInstance(null);        System.out.println(p.name);    }    //反射构造函数:public Person(String name)    @Test    public void test2() throws Exception{        Class clazz =  Class.forName("cn.itcast.eclipse.Person");               Constructor c =  clazz.getConstructor(String.class);        Person p = (Person) c.newInstance("小米");        System.out.println(p.name);    }    //反射构造函数:public Person(String name,int password)    @Test    public void test3() throws Exception{        Class clazz =  Class.forName("cn.itcast.eclipse.Person");               Constructor c =  clazz.getConstructor(String.class,int.class);        Person p = (Person) c.newInstance("小米",4000);        System.out.println(p.name);    }    //反射构造函数:private Person(List list)    @Test    public void test4() throws Exception{        Class clazz =  Class.forName("cn.itcast.eclipse.Person");               Constructor c =  clazz.getDeclaredConstructor(ArrayList.class);        c.setAccessible(true);  //暴力反射        Person p = (Person) c.newInstance(new ArrayList());        System.out.println(p.name);    }    //创建(通过无参构造函数)对象的另外一种途径    @Test    public void test5() throws Exception{        Class clazz =  Class.forName("cn.itcast.eclipse.Person");               Person p =  (Person)clazz.newInstance();        System.out.println(p.name);    }}public class Person {    public String name = "xiaoming";    public Person(){        System.out.println("person");    }    public Person(String name){        System.out.println(name);    }    public Person(String name,int password){        System.out.println(name+":"+password);    }    private Person(ArrayList list){        System.out.println("list");    }}        
私有的东西只能被内部访问,但是反射类可以实现。

反射类的方法:
利用Method执行方法

1.Method对象提供了如下方法,用于执行它所代表的方法:Object invoke(Object obj, Object... args)       对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。2.练习:使用Method分别执行无参,有参,多参(带数组和基本数据类型),静态,私有的方法。另:jdk1.4和jdk1.5的invoke方法的区别:    jdk1.5:Object invoke(Object obj,Object...args)    jdk1.4:Object invoke(Object obj,Object[] args)示例://反射类的方法public class Demo2 {    //反射类的方法:public void aa1()    @Test    public void test1() throws Exception{        Person p =new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Method method = clazz.getMethod("aa1", null);        method.invoke(p, null);    }    //反射类的方法:public void aa1(String name,int password)    @Test    public void test2() throws Exception{        Person p =new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Method method = clazz.getMethod("aa1", String.class,int.class);        method.invoke(p, "xiaoming",20);    }    //反射类的方法:public Class[] aa1(String name,int[] passwprd)    @Test    public void test3() throws Exception{        Person p =new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Method method = clazz.getMethod("aa1", String.class,int[].class);        method.invoke(p, "laowang",new int[]{1,23});    }    //反射类的方法:private void aa1(InputStream in)    @Test    public void test4() throws Exception{        Person p =new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Method method = clazz.getDeclaredMethod("aa1", InputStream.class);        method.setAccessible(true);        method.invoke(p, new FileInputStream("D:\\practice1.txt"));    }    //反射类的方法:public static void aa1(int num)    @Test    public void test5() throws Exception{//      Person p =new Person();   //静态方法调用时可以不需要对象        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Method method = clazz.getMethod("aa1", int.class);        method.invoke(null, 23);    }}public class Person {    public String name = "xiaoming";    public Person(){        System.out.println("person");    }    public void aa1(){        System.out.println("aa1");    }    public void aa1(String name,int password){        System.out.println(name+":"+password);    }    public Class[] aa1(String name,int[] passwprd){        return new Class[]{String.class};    }    private void aa1(InputStream in){        System.out.println(in);    }    public static void aa1(int num){        System.out.println(num);    }    public static void main(String[] args) {        System.out.println("main!");    }}
反射类的main方法://反射类的方法:public static void main(String[] args)     @Test    public void test6() throws Exception{//      Person p =new Person();           Class clazz = Class.forName("cn.itcast.eclipse.Person");        Method method = clazz.getMethod("main", String[].class);//      method.invoke(null, new Object[]{new String[]{"aa","bb"}});  //方式一        method.invoke(null, (Object)new String[]{"aa","bb"});  //方式二        //jdk1.5为了兼容jdk1.4,在传入的参数是一个数组时,会把数组的元素拆成多个参数进行传递。    }

反射类的字段

//反射字段public class Demo2 {    //反射字段: public String name = "xiaoming";    @Test    public void test1() throws Exception{        Person p = new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Field f = clazz.getField("name");        //获取字段的值        Object value = f.get(p);        //获取字段的类型        Class type = f.getType();        if(type.equals(String.class)){            String svalue = (String)value;            System.out.println(svalue);        }        //设置字段的值        f.set(p, "xxxx");    }    //反射字段: private int password;    @Test    public void test2() throws Exception{        Person p = new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Field f = clazz.getDeclaredField("password");        f.setAccessible(true);        System.out.println(f.get(p));    }    //反射字段:     private static int age;  和访问私有成员变量一样    @Test    public void test3() throws Exception{        Person p = new Person();        Class clazz = Class.forName("cn.itcast.eclipse.Person");        Field f = clazz.getDeclaredField("age");        f.setAccessible(true);        System.out.println(f.get(p));    }}public class Person {    public String name = "xiaoming";    private int password = 12;    private static int age = 32;    public Person(){        System.out.println("person");    }

7.内省操作:introspector类

1.开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象(javabean)的属性。2.什么是Java对象的属性和属性的读写方法:public class Person {    //javabean,这个bean有4个属性(包括getClass()属性)。    private String name;    //字段    private String password;        private int age;    public String getName() {   //属性        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}3.内省访问javabean属性的两种方法:①通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获得属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。②通过 PropertyDescriptor类操作Bean的属性。//使用内省api操作bean的属性public class Demo2 {    //得到bean的所有属性    @Test    public void test1() throws Exception{        BeanInfo info =  Introspector.getBeanInfo(Person.class,Object.class); //不要class属性        PropertyDescriptor[] pds = info.getPropertyDescriptors();        for(PropertyDescriptor pd:pds){            System.out.println(pd.getName());        }    }    //操作bean的指定属性:age    @Test    public void test2() throws Exception{        Person p = new Person();        PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);        //得到属性的写方法,为属性赋值        Method method =  pd.getWriteMethod();  //setAge        method.invoke(p, 45);        //获得属性的值        method = pd.getReadMethod();                                System.out.println(method.invoke(p, null));    }        //获取当前操作的属性的类型        @Test        public void test3() throws Exception{            PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);            System.out.println(pd.getPropertyType());    }}

使用beanUtils操作javabean的属性

//使用beanUtils操作bean的属性public class Demo1 {    @Test    public void test1() throws IllegalAccessException, InvocationTargetException{        Person p = new Person();        BeanUtils.setProperty(p, "name", "xcc");        System.out.println(p.getName());    }    //下面的代码有问题的,因为beaUtils框架只支持基本数据类型转换。    @Test    public void test2() throws IllegalAccessException, InvocationTargetException{        String name = "xiaoming";        String password = "123";        String age = "34";        String birthday = "1980-09-09";  //需要注册转换器        //为了让日期赋到bean的birthday属性上,我们给beanUtils注册一个日期转换器        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");                try {                    return df.parse(str);                } catch (ParseException e) {                    throw new RuntimeException(e);//异常链不能断                                  }               }                   }, Date.class);        Person p = new Person();        BeanUtils.setProperty(p, "name", name);        BeanUtils.setProperty(p, "password", password);        BeanUtils.setProperty(p, "age", age);  //自动将字符串转换为int。但是只支持8基本数据类型        BeanUtils.setProperty(p, "birthday", birthday);        System.out.println(p.getName());        System.out.println(p.getPassword());        System.out.println(p.getAge());        System.out.println(p.getBirthday());    }    //使用beanUtils自己的转换器,但是写的不健壮。比如日期类“”传入会报错    @Test    public void test3() throws IllegalAccessException, InvocationTargetException{        String name = "xiaoming";        String password = "123";        String age = "34";        String birthday = "1980-09-09";  //需要注册转换器        //为了让日期赋到bean的birthday属性上,我们给beanUtils注册一个日期转换器        ConvertUtils.register(new DateLocaleConverter(), Date.class);        Person p = new Person();        BeanUtils.setProperty(p, "name", name);        BeanUtils.setProperty(p, "password", password);        BeanUtils.setProperty(p, "age", age);  //自动将字符串转换为int。但是只支持8基本数据类型        BeanUtils.setProperty(p, "birthday", birthday);        System.out.println(p.getName());        System.out.println(p.getPassword());        System.out.println(p.getAge());        Date date = p.getBirthday();        System.out.println(date.toLocaleString());    }    //用map集合中的值,填充bean的属性    @Test    public void test5() throws IllegalAccessException, InvocationTargetException{        Map map = new HashMap();        map.put("name", "xiaoming");        map.put("password", "123");        map.put("age", "23");        map.put("birthday", "1980-09-09");        ConvertUtils.register(new DateLocaleConverter(), Date.class);        Person p =new Person();        BeanUtils.populate(p, map);        System.out.println(p.getName());        System.out.println(p.getPassword());        System.out.println(p.getAge());        System.out.println(p.getBirthday());    }}
原创粉丝点击