Java基础加强笔记

1.         MyEclipse是Eclipse的一个插件,此插件可以对Eclipse的功能进行扩展。使Eclipse可以开发JAVAEE的项目,为了避免安装的复杂度,MyEclipse厂商将MyEclipse和Eclipse整合到了一起。在开发时只要安装Eclipse工具即可

2.         IDE  itegrity  development  environment(集成开发环境)

3.         一个工作间包含多个工程,对一个工作间的设置会影响到这个工作间下的所有工程

4.         File —— Switch WorkSpace—— Other新建一个工作间

5.         File —— Switch WorkSpace切换工作间

6.         为工作间配置内容助理快捷键

Window —— Preferences —— General——Keys —— Content Assist —— Binding(Alt+/) ——Apply

若已有快捷键但不是Alt+/则需Unbind Command然后再重新绑定

若Alt+/已被另一个命令所占用则需将其Remove Binding

最后Apply即可

 

7.         视图是一个个的小窗口,透视图是很多个视图的集合

8.         若某个视图被关闭了可以通过 Window —— Show View —— Other来打开关闭的视图

9.         某个程序的JRE的版本比编译器的版本低则程序运行时时会被:Bad version number

为了保证程序正常运行要让JRE与编译器的版本号保持一致

10.     一个工作间进行了某种功能的设置,则这个工作间下的所有工程都会受到影响。这就是继承的一个体现。若这个工作间下的某个工程要想拥有自己独特的设置,则只需对该工程进行设置即可。这就是覆盖的一个体现。

 

11.     eclipse中配置java模板代码

案例:配置try…finally

Window ——Preferences —— Java —— Editor —— Templates —— New

Name: tryf

Pattern:

try{

    ${line_selection}

}finally{

    ${cursor}

}

    最后 Apply即可

 

12.     在MyEclipse中导入已有工程时报错,只需把该工程的JRE给Remove掉然后换成MyEclipse中自动的JRE即可

13.     Libray(库)中封装了很多JAR,添加一个库就相当于添加了很多个JAR

14.     import语句可以导入一个类或者某个包中的所有类

15.     import static 语句导入一个类中的某个静态方法或所有静态方法

16.     JDK1.5的新特性:

①     静态导入

②     可变参数

③     基本数据类型的自动拆箱和装箱

④     枚举

⑤     注解

⑥     泛型

 

17.     静态导入例子

导入一个类中的某个静态方法

import  static  java.lang.Math.max;

导入一个类中的所有静态方法

import  static  java.lang.Math.*;

18.     可变参数的特点:

①     只能出现参数列表的最后

②     …位于变量类型和变量名之间,前后有无空格都可以

③     调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。

 

19.     增强for语法:

for(type 变量名:集合变量名){…}

注意事项:

①     迭代变量必须在()中定义

②集合变量可以是数组或实现了Iterable接口的集合类

 

20.     对于int类型的数据,若其取值范围是 -128到127之间,则在将其装箱成Integer类型时,2个Integer类型的变量的内存地址是相同的

如:Integer  i1=55;

       Integer  i2=55;

       i1==i2; //true

 

21.     享元模式(flyweight):有很多个小的对象,因为它们有很多属性相同,就把它们变成一个对象,不同的属性变成方法的参数。这些参数称之为外部状态,相同的属性称之为内部状态

22.     枚举可以让某个类型的变量的取值只能是若干个固定值中的一个

枚举就相当于一个类,其中可以定义构造方法,成员变量,普通方法和抽象方法

枚举元素必须位于枚举体中的最开始的部分,枚举元素列表的后吗要用分号和其它成员分隔

枚举只有一个成员时,就可以作为一种单例的实现方式

23.     自定义一个枚举

publicabstractclass WeekDay1 {

    private WeekDay1(){}

    //抽象类不能够创建对象,必须由其子类去实现抽象类中的方法

    publicstaticfinal WeekDay1MON=new WeekDay1(){

       @Override

       public WeekDay1 nextDay() {

            return SUN;

       }

    };

    publicstaticfinal WeekDay1SUN=new WeekDay1(){

       @Override

       public WeekDay1 nextDay() {

            return MON;

       }

    };
    
    //抽象方法必须定义在抽象类中

    publicabstract WeekDay1 nextDay();

    public String toString(){

       returnthis==MON?"MON" : "SUN";

    }

}

publicclass EnumTest {

        publicstaticvoid main(String[] args) {

           WeekDay1 weekDay=WeekDay1.SUN;

           System.out.println(weekDay.nextDay());

        }

}

 

24.     枚举就是一个类,类中的元素就是枚举的对象,枚举重写了Object类中的toString方法

25.     枚举中的方法

publicclass EnumTest {

    publicstaticvoid main(String[] args) {

       WeekDay day=WeekDay.SUN;

       //枚举重写了Object类中的toString()

       System.out.println(day);

       //打印枚举的名称

       System.out.println(day.name());

       //返回当前枚举值的位置

       System.out.println(day.ordinal());

       //将字符串变成枚举对象

       System.out.println(WeekDay.valueOf("MON"));

       //获取枚举值对象数组的长度

        System.out.println(WeekDay.values().length);
    }


    publicenum WeekDay{

       SUN,MON,THU,WEN,THI,FRI,SAT

    }

}


26.     带有构造方法的枚举

publicclass EnumTest {

 

    publicstaticvoid main(String[] args) {

       WeekDay weekDay2=WeekDay.SUN;

    }


    publicenum WeekDay{

       SUN(1),MON,THU,WEN,THI,FRI,SAT;

       private WeekDay(){System.out.println("first");}

       private WeekDay(int day){System.out.println("second");}

    }

}

在创建枚举对象时默认调用无参构造方法

 

27.     带有抽象方法的枚举

publicenum TrafficLamp{

       //若枚举中有抽象方法,则枚举中的元素要重写抽象方法

       //若枚举中有有参构造方法,则枚举中的元素必须显示的调用此构造方法

       RED(30) {

           @Override

           public TrafficLamp nextLamp() {

              return GREEN;

           }

       },GREEN(54) {

           @Override

           public TrafficLamp nextLamp() {

              return YELLOW;

           }

       },YELLOW(5) {

           @Override

           public TrafficLamp nextLamp() {

              return RED;

           }

       };

       

       publicabstract TrafficLamp nextLamp();

       privateinttime;

       private TrafficLamp(int time){

           this.time=time;

       }

}


28.     Java程序中的各个Java类属于同一个事物,描述这类事物的Java类名就是Class

29.     每一个字节码就是一个Class实例对象

30.     Class.forName的作用:返回类的字节码

31.     获取字节码对应的实例对象的三种方式:

类名.class如:System.class

对象.getClass()如:new Date().getClass()

Class.forName(“类名”)如:Class.forName(“java.util.Date”)

32.     反射就是把Java类中的各种成分映射成相应的Java类

33.     Constructor类代表某个类中的一个构造方法

①     获取某个类中的所有构造方法

如:Constructor [ ] cns=Class.forName(“java.lang.String”).getConstructors();

②     获取某一个构造方法

Constructor cns=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

③     用反射生成对象

Constructor c=String.class.getConstructor(StringBuffer.class);

String str=c.newInstance(new StringBuffer("abc"));

 

④     Class.newInstance() 用默认的构造方法创建实例对象

此方法底层用到了缓存机制来保存默认构造方法的实例对象

 

34.     成员变量的反射

publicclass ReflectPoint {

  private int x;

  public int y;

  public ReflectPoint(int x,int y) {

     super();

     this.x = x;

     this.y = y;

  }

}

publicclass ReflectTest {

    publicstaticvoid main(String[] args)throws Exception{

      ReflectPoint rp=new ReflectPoint(3, 5);

       //访问共有变量

       Field fieldY=rp.getClass().getField("y");

      System.out.println(fieldY.getName()+"::"+fieldY.getInt(rp));


       //访问私有变量

       Field fieldX=rp.getClass().getDeclaredField("x");

      fieldX.setAccessible(true);

      System.out.println(fieldX.getName()+"::"+fieldX.getInt(rp));

  }

} 

35.     成员变量反射的综合案例 

将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的”b”改成”a”

 

publicclass ReflectPoint {

    private int x;

    public int y;

    public Stringstr1="ball";

    public Stringstr2="basketball";

    public Stringstr3="itcast";

    public ReflectPoint(int x,int y) {

       super();

       this.x = x;

       this.y = y;

    }

  
    @Override
    public String toString() {
       returnstr1+":"+str2+":"+str3;

    }

}


publicclass ReflectTest {

    publicstaticvoid main(String[] args)throws Exception{

       ReflectPoint rp=new ReflectPoint(3, 5);

       changeStringValue(rp);

       System.out.println(rp);

    }


    privatestaticvoid changeStringValue(Object obj)throws Exception{

       Field[] fields=obj.getClass().getFields();

       for(Field field : fields){

           Type type=field.getType();

           if(type==String.class){

              String oldVal=(String)field.get(obj);//获取某个对象中的字段

              if(oldVal.contains("b")){

                  String newVal=oldVal.replace("b","a");

                  field.set(obj, newVal);

              }

           }

       }

    }

}

36.     成员方法的反射

Method类代表某个类中的一个成员方法

如:

String str="abc";

       //str.chaAt(2);

       Method m=String.class.getMethod("charAt",int.class);

    System.out.println(m.invoke(str, 2));

 

37.     对接收数组参数的成员方法进行反射

publicclass ReflectTest {

    publicstaticvoid main(String[] args)throws Exception{

       Class startingClassName=Class.forName(args[0]);

       Method m=startingClassName.getMethod("main", String[].class);

//     m.invoke(null, (Object)new String[]{"11","22","33"});

       m.invoke(null,new Object[]{new String[]{"11","22","33"}});

}

}

class ParameterTest{

    publicstaticvoid main(String[] args) {

       for(String arg : args){

           System.out.println(arg);

       }

    }

}
 

当把一个字符串数组作为参数传递给invoke方法时,按jdk1.5的语法,会把这个参数当作是一个字符串数组,而按jdk1.4的语法,会把字符串数组打散成为若干个单独的参数;java在执行代码时,会按照jdk1.4的语法去处理

 

38.     反射会影响程序的性能

39.     数组也是Object类型的元素

40.     具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象

41.     代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class

42.     基本类型的一维数组可以被当做Object类型使用

43.     非基本类型的一维数组既可以当做Object类型使用,又可以当做Object[ ]类型使用

44.     Arrays.asList()方法处理int[ ]和 String[ ]是有差异的,它会把int[ ]当成一个元素去处理,把String[ ]中的每一个元素当成一个元素去处理。这是因为在jdk1.4中asList接收的参数类型是Object[]而jdk1.5中asList接收的参数类型是可变参数。

45.     数组与Object的关系及其反射类型

①int[ ] a1=new int[3];

②int[ ] [ ] a2=new int[2][3];

③String [ ] a3=new String[3];

②, ③均属于Object[ ]类型

①属于Object类型

 

46.     数组的反射

Array工具类用于完成对数组的反射操作

如:

private static void printObj(Object obj) {

       Class clazz=obj.getClass();

       if(clazz.isArray()){

           int len=Array.getLength(obj);

           for(int x=0; x<len; x++){

              System.out.println(Array.get(obj, x));

           }

       }else{

           System.out.println(clazz);

       }

}
 


main方法中定义函数:

printObj(a4);

printObj("abc");

 

47.     Object类中的equals()方法比较的是内存地址(hashCode值)

48.     当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存进HashSet集合中的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

 

49.     获取资源文件的2中方式:

//必须写上资源文件的完整路径

//InputStream is=ReflectTest2.class.getClassLoader().getResourceAsStream("cn/itcast/day1/resource/Info.properties");

      

//路径写资源文件相对于本java文件所在目录("cn/itcast/day1)即可

InputStream is=ReflectTest2.class.getResourceAsStream("resource/Info.properties");

 

50.     内省(IntroSpector)

需要导入的包:commons-beanutils-1.8.3.jar     commons-logging-1.1.2.jar

ReflectPoint rp=new ReflectPoint(3, 5);

BeanUtils.getProperty(rp,"x").getClass().getName();//java.lang.String                              

BeanUtils.setProperty(rp, "x", 9);

 

51.     一个注解就是一个类,当用到某个注解时就相当于创建了这个注解的对象

52.     注解可以加在包,类,字段,方法,方法的参数以及局部变量上

53.     基本的注解:

①     @SuppressWarnings(“deprecation”)      告知编译器不要提示方法过时

②     @Deprecated   告知编译器该方法已过时

③     @Override      告知编译器该方法是覆盖父类的方法

 

54.     注解的使用

@Retention(RetentionPolicy.RUNTIME)

用于指定注解的生命周期在哪个阶段(CLASS,RUNTIME,SOURCE)

SOURCE—源代码阶段

CLASS—源代码编译后的CLASS文件阶段

RUNTIME—类加载器将CLASS文件加载进内存阶段

 

@Target({ElementType.METHOD,ElementType.TYPE})

用于指定注解可以标识的位置,即可以标识在方法上,也可以标识在类,枚举,接口上,等;

 

55.     元注解:注解的注解

56.     为注解增加各种属性

public@interfaceMetaAnnotation {

    String value();

}

 

//@Retention --指定注解的声明周期

@Retention(RetentionPolicy.RUNTIME)//类加载器将CLASS文件加载进内存阶段

//@Target --指定注解的标注位置

@Target({ElementType.METHOD,ElementType.TYPE})//可以将注解标注在方法,类,接口,枚举上

public@interfaceItcastAnntation {

    //注解中的属性类似于方法,属性名后都带()

    //注解的返回值类型:8种基本数据类型,String,Class,enum,Array,注解

    //定义枚举的属性

    String color() default"blue";

   //若枚举中只有一个value属性时,在设置value属性时可以省略value=

    String value();

    //定义数组属性

    int[] arr()default {3,4,5};

    //定义枚举属性

    EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;

    //定义注解属性

    MetaAnnotation annotationAttr()default@MetaAnnotation("zhujieshuxing");

    //定义Class属性

    Class clazz() default Object.class;

}

//若数组属性中只有一个元素,属性值可以省略大括号

@ItcastAnntation(clazz=String.class,annotationAttr=@MetaAnnotation("invoke zhujieshuxing"),color="red",value="abc",arr=1)

publicclass AnnotationTest {

    @SuppressWarnings("deprecation")

    @ItcastAnntation("xyz")

    publicstaticvoid main(String[] args) {

       System.runFinalizersOnExit(true);

       

       //检查该类上是否有注解

       if(AnnotationTest.class.isAnnotationPresent(ItcastAnntation.class)){

           ItcastAnntation annotation=AnnotationTest.class.getAnnotation(ItcastAnntation.class);
    

           //调用注解的属性

             System.out.println(annotation.color());

           System.out.println(annotation.value());

           System.out.println(annotation.arr().length);

           System.out.println(annotation.lamp().nextLamp());

           System.out.println(annotation.annotationAttr().value());

           System.out.println(annotation.clazz().getName());

       }

    }


57.     泛型的内部原理

泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,如,用反射得到集合,再调用其add方法即可。

 

举例:

publicclass GenericTest {

    publicstaticvoid main(String[] args)throws Exception{

       ArrayList<String> col1=new ArrayList<String>();

       ArrayList<Integer> col2=new ArrayList<Integer>();

       System.out.println(col1.getClass() == col2.getClass());

       

       //用反射往col2中添加字符串元素

       col2.getClass().getMethod("add",Object.class).invoke(col2,"abc");

       System.out.println(col2.get(0));

    }

}
 

58.    ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:

ArrayList<E> 泛型类型,E:类型参数

ArrayList<Integer> 泛型参数类型,Integer:实际类型参数

< > 念typeof

ArrayList:原始类型

 

59.     泛型中的类型不存在父子关系

60.     即Collection<Object>与Collection<Integer>不存在等号关系

61.     编译器不允许创建类型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型。

62.     泛型中通配符的使用

①使用?通配符可以引用其它各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

②泛型中的?通配符扩展

1)        限定通配符的上界

Vector<? extends Number> x = new Vector<Integer>();

?— Number或Number的子类

2)        限定通配符的下界

Vector<? super Integer> x = new Vector<Number>();

?— Integer或Integer的父类

 

提示:限定通配符总是包括自己

 

63.     只有引用类型才能作为泛型方法的实际参数。

publicstatic <T>void swap(T[]arr,int x,int y){

       T temp=arr[x];

       arr[x]=arr[y];

       arr[y]=temp;

}

swap(new String[]{"aa","bb","cc"},1,2);


64.     Arrays.asList()不能转换Int类型的数组

65.     <T>一般放在方法的修饰符之后,方法的返回值之前

66.     普通方法,构造方法和静态方法中都可以使用泛型

67.     静态方法不能使用类定义的泛形,而应单独定义泛形

68.     用反射获取泛型的实际类型参数

publicclass GenericTest {

    publicstaticvoid main(String[] args)throws Exception{

       Method m=GenericTest.class.getMethod("applyVector", Vector.class);

       Type[] type=m.getGenericParameterTypes();

       ParameterizedType pt=(ParameterizedType)type[0];

       System.out.println("原始类型:"+pt.getRawType());

       System.out.println("实际类型参数:"+pt.getActualTypeArguments()[0]);

 

}

}

publicstaticvoid applyVector(Vector<Date> v1){
     

}

69.     Java虚拟机中可以安装多个类加载器,系统默认三个主要的类加载器,每个类加载器负责加载特定位置的类。

BootStrap      ExtClassLoader    AppClassLoader 

70.     类加载器:加载类的工具

71.     rt.jar:存放java系统提供的类

72.     有包名的类不能调用无包名的类

73.     类加载器的委托机制

每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其它的类装载器去加载类,这就是类加载器的委托模式。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就报ClassNotFoundException异常

74.     当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢

首先当前线程的类加载器去加载线程中的第一个类

若类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B

还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类

75.     安全,事务,日志等功能要贯穿到好多个模块中,所以称它们为交叉业务

76.     交叉业务的编程问题即为面向方面的编程(Aspect  oriented  program简称AOP)AOP的目标就是要使交叉业务模块化

77.     代理是实现AOP功能的核心技术

78.     动态代理类:JVM在运行期动态生成的类的字节码

79.     CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,故要为一个没有实现接口的类生成动态代理类,可以使用CGLIB库

80.     把切面代码用对象的方式进行封装,并以对象的方式进行传递,执行对象就相当于执行切面的代码

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章