java基础笔记1

来源:互联网 发布:淘宝1元定金 编辑:程序博客网 时间:2024/04/29 02:21

1.  初始化执行顺序:

class Test1
{
Test1(String strClass){
Log.i("zy",strClass+":test1构造");
}
}


class Test2
{
Test2(String strClass){
Log.i("zy",strClass+":test2构造");
}
}


class Test3
{
public Test1 test1 = new Test1("Test3");
static public Test2 test2 = new Test2("Test3");
Test3(){
Log.i("zy","test3构造");
}
}


class Test4 extends Test3
{
public Test1 test1 = new Test1("Test4");
static public Test2 test2 = new Test2("Test4");
Test4(){
Log.i("zy","test4构造");
}
}

先测试非继承情况下:

Test3 test3 = new Test3();

06-09 09:04:24.264: I/zy(1004): Test3:test2构造
06-09 09:04:24.264: I/zy(1004): Test3:test1构造
06-09 09:04:24.264: I/zy(1004): test3构造

静态成员变量(或静态区块)初始化->非静态成员变量初始化->本类构造函数


再测试继承情况:

Test4 test4 = new Test4();

06-09 09:02:34.234: I/zy(753): Test3:test2构造
06-09 09:02:34.234: I/zy(753): Test4:test2构造
06-09 09:02:34.234: I/zy(753): Test3:test1构造
06-09 09:02:34.234: I/zy(753): test3构造
06-09 09:02:34.234: I/zy(753): Test4:test1构造
06-09 09:02:34.234: I/zy(753): test4构造

父类静态成员变量(或静态区块)初始化->本类静态成员变量(或静态区块)初始化->父类非静态成员变量初始化-父类构造函数->本类非静态成员变量初始化->本类构造函数

对于非静态成员,都是先父类后子类(执行完父类的成员变量初始化和构造函数后再执行子类的成员变量初始化和构造函数),但是静态变量会优先于所有之前初始化(也是先父后子)

java不同于c++,变量(静态和非静态都一样)只在相应类装载时才初始化(new出一个对象时),比如上例中如果只是声明:static public Test2 test2,而没有new,则不会调用Test2中构造函数



2.  Java类在编译后会自动加上一个class对象,用于RTTI,class对象可由class.forname(类名)静态方法或类名.class静态对象获取,class可动态创建对象,获取类名等,这就是反射

AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。



3.  接口可以多继承

4.  接口的数据成员都是final static,所有成员都是public

        static:静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。

 java中的static不能用于局部变量,所以static只能修饰成员变量,成员函数和区块,修饰成员变量和函数时,可以通过类名访问,静态区块优先初始化

      final:final类不能被继承,没有子类,final类中的方法默认是final的。
      final方法不能被子类的方法覆盖,但可以被继承。
      final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
      final不能用于修饰构造方法。    

     final static可以理解为全局常量  


5.  内部类(接口)可以是public,protected和pravite属性,private属性的内部类(接口)在外部不可访问,非内部类只有public和package权限

内部类(接口)属性为protected时,本包内可以访问(可以声明protected的内部类对象),内部类为private时,可以继承一个外部接口,在宿主类中通过一个方法返回接口类型的内部类对象

6.  内部类对象在宿主类外部的定义:

COut out = new COut();

COut.Cin in = out.new CIn();

7.  可以在任意一个作用域中声明内部类

8.  内部类无论嵌套多少层,都可以访问外层各个级别宿主类成员(包括private),匿名内部类也一样

9.  匿名内部类访问局部变量时必须要求此变量为final类型,访问成员变量则不需要

10.             静态内部类称为嵌套类,它不像普通内部类有宿主类的reference,它只能访问宿主类的static成员,它内部可以有static成员(普通内部类不能有static成员)

11.             嵌套类可以包含在interface内部(包含实现)

12.             使用宿主类名.this即可引用到宿主类的reference

13.             必须有宿主类对象的reference才能new一个内部类对象,多级内部类必须一级一级创建,因为宿主类的reference需要存到内部类中,继承内部类时,也必须在子类的构造函数中传入父类的宿主类对象的reference,子类必须在构造函数第一句调用宿主类对象的super方法

14.             内部类没有虚函数特性,不能覆写,java中非final函数都是虚函数

15.             内部类可以解决需要多重继承的问题

16.             Java提供inputstreamreader类进行编码转换,它是一种字符流,先在其构造函数中指定其原字串的编码,由于字符流的read方法读出来后都是默认的编码(utf-8),当指定了原编码时,它就会把原编码转成默认编码读出来,没有指定时,默认原编码也是utf-8

字符流是编码相关的,二进制流是编码无关的,因为二进制流以字节为单位进行处理,字符流以字符为单位进行处理,一个字符(如汉字)可能有多个字节,以字节流读取汉字可能出现读到半个汉字的情况,以字符流读取,只要原编码设置正确,则不会出现这种情况

字节流即二进制流,本质上所有流都是二进制流,只是处理的单位不一样

也可以自动检测文件中字符的编码

17.             各种IO类的区别:、

a.      File类:只是用户获取文件的一些基本信息,如文件名,修改时间等,不能用于读写文件,可作为参数构造其他io类

b.      以stream结尾的为字节流,以reader结尾的为字符流

c.      以buffer打头的带缓冲区,处理更高效,一般以一个非buffer对象作为构造参数构造而成

d.      Inputstreamreader可以把字节流转成字符流,并制定原字符的编码

18.             String末尾没有结束符,用一个大buffer读取一个小字串时,再把buffer转成string,这个string是一个大串(实际小串后跟一串乱码),操作前必须取其实际小串

19.             Package:

Javac只认目录,不认包,目录可以指定为绝对路径,或当期路径的相对路径,或.classpath环境变量指定目录的相对路径,用*.java代表目录下所有的java文件,用-d指定class文件输出路径,输出的目录以-d指定目录为基准,根据包结构创建目录层级,如:

Javac –d  c:\  a.java, a.java的包为a.b

则.class文件输出到c:\a\b\中,如果无-d,则.class和.java同目录

Java命令认目录也认包,java a.b.myclass,会在相对路径a\b下查找myclass.class,同时,myclass.class中指定的包也要位package a.b

一个目录下两个文件如果都没有指定包,它们就都在一个默认包下

一般情况下,包名和文件夹名称、层级保持一致

 

 

20.             Java在实例化一个对象的时候,如果没有显式使用super(),则会先调用父类的无参构造函数(不是和自己构造函数参数数量对应的那个),然后调用子类的构造函数,如果父类不是Object类,则一直向上追溯到Object类为止,super()只能在构造函数的第一行使用,在别的地方使用均为非法

21.             默认情况下,即没有public,private,protected声明的情况下,成员为package属性(本包可见)

22.             一个.java文件只能有一个public类

23.             Package类的publicstatic成员在包外也可以访问

24.             组合类中子类只是声明,没有初始化时是不会调用构造函数的,会赋值为null,这点和c++不一样,知道初始化时才会调用其构造,但是子类的静态变量会初始化

25.             Java可以在一对大括号里执行一段初始化语句,像构造函数一样自动执行(在new时执行,static在类第一次声明时执行)

Class A

{

   Int I = 0

   {

            Int j=2;

     Print(……);

   }

}

 

Class A

{

   Int I = 0

  Static//在类第一次声明时执行

   {

            Int j=2;

     Print(……);

   }

}

26.             多维数组:

Int[][][]  a1 = newint[2][2][4];

各个维度的长度可以不一样:

Int[][]  a2 = newint[rand.nextInt(7)][]

For(int i=0;i<a2;i++)

{

    a2[i] = newint[rand.nextInt(5)];

}

27.             初始化可以执行函数:

Class A

{

    int a = print(“fun…”);

}

28.             Java中也有抽象类(abstractclass),其中含有0-n个抽象函数(abstract function),有abstract function的类必须声明为abstract class,没有abstract function的类也可以声明为abstract class,代表这个类不能实例化,只能用于继承和访问静态变量

29.             Pulibc,Protected属性即包含了package属性访问的范围

30.             Java没有析构函数

31.             由于构造的顺序,父类的构造函数如果调用了一个虚(非final)函数,很有可能子类还没有初始化好,出现一些bug,所以构造函数除本类的final函数外,最好不要调用其他函数,那样是不安全的。

32.             Java关键字区分大小写

33.             ClassA a1=new ClassA()

     ClassA a2 = newClassA();

     a2 = a1;

a2原来指向的对象变成垃圾,a2和a1指向同一个对象,也就是说对象的赋值天生就是引用的(对象做函数参数时也一样),这个和c++不一样(拷贝构造函数)

34.             比较对象是否相等要用对象的equal方法,而不是”==”,因为”==”比较的是reference,equal是object中的方法,每个类都有,但是默认行为和”==”一样,所以必须重写比较方法,每个java sdk类基本都会重写这个方法

35.             Java没有sizeof运算,不同操作系统下各种类型的字节数不变

36.             有默认构造函数,函数的重载是通过参数列表来区分的,无法通过返回值,参数的顺序也可以区分重载

37.             This表示当前对象的引用,可以在一个构造函数里调用另一个重载的构造函数,必须在函数最打头调用

38.             Java的垃圾回收只回收new出来的东西,所以一些独立于jvm的连接必须手工close,否则内存泄露,如文件,数据库,不close会内存泄露

没有reference的对象才会被回收,java对变量名得操作都是操作reference,比如把一个对象放入集合,它和外面的reference实际对象是同一个

Vector v = new vector()

Object o = new object()

v.add(o);//V[0]和o是同一个对象

o=null,同时v.removeelementat(0)才会使object对象回收

39.             System.gc()告知垃圾回收系统强制回收,但是不保证马上执行

40.             不用new使,数组不需要也不能在声明时给出大小:

   Int a[] = {1,2,3};

   Int b[]

   b = a;

用new时,数组大小可以动态获取

Integer[] a = new Integer[rand.nextInt(20)];

Integer[] b = new Integer[]{new Integer (1), new Integer(2)……}

41.             数组创建、初始化

两种创建方式:

         1.无new:

type var[]; 或type[] var;//声明数组时不能指定其长度(数组中元素的个数),

         2.有new:Java中使用关键字new创建数组对象,格式为:

数组名 = new 数组元素的类型 [数组元素的个数]

三种初始化:

1. 静态初始化:在定义数组的同时就为数组元素分配空间并赋值

         int a[] = {0,1,2} ;

 

2. 动态初始化:数组定义与为数组分配空间和赋值的操作分开进行

a = new int[3] ; 

         a[0] = 0 ; 

         a[1] = 1 ; 

         a[2] = 2 ;

3. .默认初始化:数组是引用类型,它的元素相当于类的成员变量,因此数组分配空间后,每个元素也被按照成员变量的规则被隐士初始化

           int a [] = new int [5] ;    

           System.out.println("" + a[3]) ;



42.             对象的reference都为都赋值null或都指向其他对象时,变成垃圾

     对象的作用域超出时变成垃圾

    

43.基本类型和基本类型变量被当作参数传递给方法时,是值传递。在方法实体中,无法给原变量重新赋值,也无法改变它的值。
对象和引用型变量被当作参数传递给方法时,是引用传递。在方法实体中,可以改变它所指向对象的属性。

 

44.


private:仅对本类是可见的;

public:对所有类都是可见的;

protected:对本包(package)及所有子类是可见的;


 45.java中装箱和拆箱

装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float

拆箱:和装箱相反,将引用类型的对象简化成值类型的数据

Integer a = 100;                  这是自动装箱  (编译器调用的是static Integer valueOf(int i))
int     b = new Integer(100); 这是自动拆箱


 

原创粉丝点击