java基础知识点

1、使用浮点型数值时,默认的类型是double,后面加上f或F才被识别为float类型。
2、使用数组前一定要先开辟内存空间,当然也可以直接用静态赋值的方式。
3、Java中的基本数据类型变量为全局变量(确切地说,是类中的属性域的变量,java中是没有全局变量的)时,可以不赋值,直接使用,因为有默认值,但是作为局部变量时,就必须在赋值后才能使用,而对于引用数据类型,无论是全局还是局部变量,都会被赋予默认值null。另外,凡是用new关键字新建出来的对象或数组等,对象或数组里面的基本类型都被初始化了默认值,用static关键字声明的变量也被初始化为了默认值。关于默认值,boolean类型数据的默认值是false,String以及类对象的默认值为null,其他的为0,0.0f,0.0等。
4、任何数据类型碰到String类型的变量或常量之后都会向String类型转换。
5、引用数据类型:类似于C/C++中的指针,这种变量在声明时不会分配内存,必须另外进行开辟内存空间的操作,如类和数组均属于这种数据类型。
6、由于数组是引用数据类型,因此在数组操作中,栈内存中保存的永远是数组的访问地址(即引用,相当于C/C++中的指针),只开辟栈内存空间的数组是无法使用的,必须有指向的堆内存才可以使用,要想开辟堆内存则必须使用关键字new,然后只是将此堆内存的使用权交给了对应的栈内存空间,而且一个堆内存空间可以同时被多个栈内存空间所指向。
【java基础知识点】7、由main方法直接调用的方法,要用static关键字声明。
8、当使用new关键字实例化对象时,才会调用构造方法。
9、匿名对象就是没有明确给出名称的对象,一般匿名对象只使用一次,而且匿名对象只在堆内存或常量池中开辟空间,而不存在栈内存的引用。
10、比较对象时,使用“==”,是对对象的引用进行比较,而用equals方法,则是对对象的内容进行比较。equals方法是Object类中的方法,它默认的行为是比较引用,类库中的类都将其覆写为了比较内容的方法,对于自定义类,我们需要实现自己将其覆写为比较内容的方法。
11、String类的两种实例化方式的区别:
首先,一个字符串就是一个String类的匿名对象,匿名对象就是已经开辟了内存空间的并可以直接使用的对象。
第一种:String str1 = “ hello”
实际上这种实例化方式就是把一个在常量池中开辟好的内存空间的使用权交给了str1对象,而使用这种方式还有另外一个好处,就是如果一个字符串已经被一个名称所引用,则以后再有相同的字符串声明时,就不会在重新开辟新的空间,而继续使用已经开辟好的空间,比如:String str1 = “hello”与String str2 = “hello”中的str1和str2都指向同一块常量池内存。这在Java中成为“共享设计”。
第二种:String str1 = new String(“hello”)
由于一个字符串是一个String类的匿名对象,因此它已经开辟了一个常量池的内存空间,而如果使用new关键字,不管如何都会再开辟一个新的堆内存空间,但此时,此空间的内容还是“hello”,所以这种实例化方式实际上是开辟了两个内存空间,但真正使用的只是使用new关键字开辟出的堆内存空间,另外一个是常量池中的则是垃圾空间。
12、在使用String类进行操作时,特别重要的一点:字符串的内容一旦声明则不可改变。在程序中,改变String类对象的内容时,实际上是改变了String类对象的引用,将其指向了其它字符串所在的地址,这样是很耗费内存资源的,因此,如果在开发中遇到改变很多次String类对象内容的时候,一定要用StringBuffer类代替完成。
13、关于引用传递(针对引用数据类型)和值传递(针对基本数据类型)(实际上Java中是没有引用传递的,所有的参数传递都是值传递,这里说引用传递是为了便于理解):
1)所谓引用传递就是指将堆内存空间的使用权交给多个栈内存空间,引用传递的参数类型只能是类对象或者数组的引用等引用数据类型。而值传递,其形参是基本数据类型,方法调用时,实际参数把它的值传给对应的形式参数,形参只是用实参来初始化自己的存储单元,它与实参是两个不同的存储单元(形参只是方法外面传入的值的一个副本),所以方法执行后,形参值的改变不会影响实参值。
2)一般对象类,在进行引用传递(确切地说,还是值传递,只不过这里的实参在方法中的副本为对象的引用)操作,对类中属性的值进行修改后,操作有效(虽然引用是副本,但形参和实参指向的是同一块堆内存,因此通过形参,也即是引用的副本,改变堆内存中实例的相关信息,这种改变肯定会保存下来),会改变原来对象中属性的值(注意,String这种不可变的类是个例外,而且匿名构造的String实例是保存在方法区中的常量池中的)。
3)一般对象类,在进行引用传递操作时,如果在方法内,将形参指向了其他实例,即改变了引用的值(注意,不是堆内存中实例的值),很明显,这种情况只是改变了方法中引用副本的值,而对实参的值(指的是实参引用,而不是堆中的对象实例)是没有影响的,也即是说实参还是指向之前的实例。
4)把数组作为形参进行引用传递时会影响到实参数组内元素的值。
14、使用this()调用构造方法时有两点需要注意的:
1)由于构造方法是在实例化对象时被自动调用的,也就是说在类的所有方法中,只有构造方法是被优先调用的,所以用this调用构造方法必须也只能放在构造方法的首行。
2)this调用构造方法时一定要留一个构造方法作为出口,即程序中至少存在一个构造方法是不使用this调用其它构造方法的。
15、static相关应用:
1)使用static关键字的属性是静态的(所有类对象共享的),可以通过静态引用修改其属性值,其结果是所有的对象中该属性值均被修改。不存在this引用。
2)使用static声明的方法,可以通过类名称直接引用。非static声明的方法可以调用static声明的属性或方法,而static声明的方法不能调用非static类型声明的属性或方法。这也并不难理解,因为在程序中所有的属性和方法必须在对象开辟堆内存之后才可以调用,而static类型的方法在对象未被实例化时就可以被类名调用,所以如果直接由static方法调用非static操作,则有可能在属性还没有被初始化时就被调用了,这一点在语法上就讲不通。
16、构造块优先于构造方法执行,而且每次实例化对象时都会执行构造块中的代码。静态代码块优先于构造方法执行,而在类中定义的静态代码块会优先于构造块执行,且不管有多少对象产生,静态代码块只执行一次。
17、单例设计模式:定义Singleton类,将构造方法私有化,用static关键字在类内部产生本类的实例化对象,再在本类中通过static方法取得Singleton类的实例。这样做的好处是:可以控制实例化对象的产生,即无论在程序中声明几个Singleton对象,但实际上只有一个Singleton类的实例化对象存在,只是产生了几个该对象的引用而已。
18、内部类唯一的好处就是可以方便地访问为本类中的私有属性。
1)static内部类的实例化方法:外部类.内部类 内部类对象 = new 外部类.内部类();
2)非static内部类的实例化方法:外部类.内部类 内部类对象 = 外部类实例.new 内部类();
19、使用static声明的内部类变成了外部类,即在外部可以直接通过外部类的名称调用,但是使用static声明的内部类不能访问外部类中的非static属性。也可以在方法中定义一个内部类,但是在方法中定义的内部类不能直接访问方法中的参数,如果方法中的参数要想被内部类访问,则参数前必须加上final关键字。
20、JAVA中常用的内存区域:
1)栈内存:保存基本数据类型的变量值,保存类中的局部变量及方法中的形参,保存数组、类对象等的引用。
2)堆内存:保存每个引用数据类型对象的具体属性内容,即由new关键字实例化的数组或对象等。

  1. 方法区中的常量池:保存基本数据类型的常量值(final声明),字符串常量值,如String str = “avc”中的“avc”字符串以及代码中的方法、类的名称等具体的字符。
4)方法区中的静态存储区:保存static声明的静态变量。
  1. java的八种基本类型(Byte Short、Integer、Long、Character、Boolean、Float、Double),除Float及Double意外,其它六种都实现了常量池,但是他们只在大于等于-128且小于等于127时才能使用常量池,如果不在此范围内,则会new一个出来,保存在堆内存中。
21、Java中只允许单继承,不能使用多重继承,但是允许进行多层继承。
22、子类对象在实例化前只会先默认调用父类中的无参构造方法,因此要在子类的构造方法中调用父类中的有参构造方法,须显式地加上super方法。
23、被子类覆写的方法不能拥有比父类方法更加严格的访问权限,当方法被覆写后,子类对象调用的方法将是被覆写后的方法,方法覆写时从private变为default不算方法的覆写,这是因为private方法被自动认为是final方法,而且对子类是屏蔽的,其实是重新定义了一个方法,这与方法的覆写没有任何关联。另外,域(即初始化变量)和静态方法均不具有多态性,如果在子类和父类中均有该域和静态方法,则即使发生向上转型,调用的域或静态方法也是父类中的,而不是子类中“覆写”的(实际上不能算是覆写,只是重复定义而已),
24、在继承类中,this和super是不允许同时出现的,因为两者调用构造时都必须放在构造方法的首行。
25、final关键字:使用final声明的类不能被继承,使用final声明的方法不能被覆写,使用final声明的变量即成为常量,不可修改,使用final声明变量时,要求全部的字母大写。如果在一个程序中的变量使用public static final声明,则此变量将成为全局常量。
26、抽象类的定义及使用规则:
1)包含一个抽象方法的类必须是抽象类。
2)抽象类和抽象方法都要使用abstract关键字声明
3)抽象方法只需声明而不需要实现。
4)抽象类必须被子类继承,子类(如果不是抽象类)必须覆写抽象类中的全部抽象方法。
5)一个抽象类不能使用final关键字声明。
6)抽象类中的抽象方法不要使用private声明。
27、接口的定义及使用规则:
1)接口有全局常量和公共的抽象方法组成。
2)接口中的抽象方法必须定义为public访问权限,在省略访问权限的时候,接口中的方法也是public权限的,这点是绝对不可改变的。
3)接口中的常量一般public static final声明,即使不声明,也默认为全局常量。
4)一个类(如果不是抽象类)实现接口也必须覆写接口中的全部抽象方法。
28、类、接口等的继承与实现关系
1)一个子类只能继承一个抽象类,但是可以实现多个接口。
2)一个接口不允许继承抽象类,但是允许继承多个接口。
3)允许一个抽象类实现多个接口。
29、多态性
多态在Java中主要有2种体现形式:方法的重载与覆写、对象的多态性。对象的多态性主要分为以下两种类型:
1)向上转型:用子类实例化父类对象或接口对象。调用被子类覆写的方法时,调用的是覆写后的方法,不可以调用子类中独有的方法(即在父类或接口中没有),要想调用,则必须进行向下转型。
2)向下转型:将实例化后的父类强制转化为其子类的实例化对象。在进行对象的向下转型前必须首先发生对象的向上转型。
30、instanceof关键字:对象 instanceof 类 ——>返回boolean类型值,对象为该类的实例化对象,则返回true,否则返回false 。
31、Object类中的equals方法默认使用的是按地址进行比较的,并不能进行对内容的比较,而在String类中覆写的方法则是进行内容比较的。
32、一切的引用数据类型都可以使用Object进行接收,包括数组和接口类型。
33、finally作为异常的统一出口,所以在此语句块的编写中尽可能不要出现像throw或return这样的语句,这样可以避免不必要的问题出现。如果在try语句中出现return,那么该return语句是在finally中的语句执行完后才执行的。
34、Exception在程序中必须使用try…catch进行处理,而RuntimeException则可以不使用try…catch进行处理,但如果有异常产生,则将交由JVM进行处理。但在开发代码时,最好也是用try…catch进行处理。
35、如果一个类中的方法全部是使用static声明的静态方法,则在导入时就可以直接使用import static的方式导入,这样在调用该类中的方法时,就不再需要使用“类.静态方法()”的形式,可以直接调用。
36、四种访问权限:
1)private访问权限:属于私有访问权限,只能在本类中进行访问。
2)default访问权限:默认的访问权限,可以被本包中的其他类所访问,但是不能被其它包中的类所访问。
3)protected访问权限:受保护的访问权限,只能被本包中的类以及不同包中的子类所访问。
4)public访问权限:公共访问权限,可以在所有的类中访问。
37多线程实现的两种方法:继承Thread类,实现Runnable接口
1)联系:两种方式,无论使用哪种,最终都必须依靠Thread类才能启动多线程,而在Thread类中的run方法调用的是Runnable接口中的run方法。
2)区别:如果一个类继承Thread,则不适合于多个线程共享资源,因为每个Thread类的实例化对象只能对应并启动一个线程,而实现Runnable接口,就可以方便地实现资源的共享,因为每个Runnalbe接口的实例化对象可以作为参数传入到多个Thread对象中,从而用一个Runnable接口的实例化对象启动多个线程。
38、由于线程操作的不确定性,所以主线程有可能最先执行完,那么此时其他线程不会受到任何影响,并不会随着主线程的结束而结束。
39、线程同步:即多个操作在同一时间段内只有一个线程进行,其它线程要等待此线程完成之后才可以继续执行。如果在普通代码块上加上synchronized关键字,则此代码块就称为同步代码块,在使用同步代码块时,必须指定一个需要同步的对象(一般为类的实例化对象)。如果在方法前加上synchronized关键字,则此方法称为同步方法。
40、多线程的开发中可以通过设置标志位的方式停止一个线程的运行,一般不建议使用Thread类中的suspend、resume、stop等方法,因为这三种方法在操作时会产生死锁问题。
41、在引用传递中,在泛型操作中可以设置一个泛型对象的范围上限和范围下限。范围上限使用extends关键字声明,表示范型的类型可能是所指定的类型或者此类型的子类,而范型下限使用super进行声明,表示泛型的类型可能是所指定的类型,或者是此类型的父类型,或是Object类。
42、一个类的子类可以通过对象多态性为其父类实例化,但是在泛型操作中,子类的泛型类型是无法使用父类的泛型类型接收的,例如:Info不能使用Info接收,因此在参数传递时不能进行向上转型,但该限制可以用通配符解决,即可以在方法的参数中使用类似Info形式的参数来接受任意类型的泛型。
43、Java允许把任何基本数据类型转换成别的基本数据类型,但布尔类型除外,它根本不允许进行任何类型的转换处理,这与C++中不同。
44、如果没有明确定义一个类的构造方法,那么编译器会自动创建一个默认的无参构造函数,在创建该类的实例对象时,会默认调用它,如果明确定义了一个构造函数(无论有没有参数),编译器都不会自动创建默认构造函数。
45、Java程序初始化的顺序是先静态对象,后非静态对象,而且静态初始化只在Class对象首次加载的时候进行一次。
46、对于类的访问权限,仅有两种选择:包访问权限(default)或public(一个内部类可以是private或protected的,但那是一个特例)。如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器指定为private,从而不让任何人创建该类的对象。
47、可以为每个类都创建一个main方法。这种技术可使每个类的单元测试都变得简便易行,而且在完成单元测试之后,也无需删除main方法,可以留待下次测试。当一个程序中含有多个类,也只有命令行所调用的那个累的main方法才会被调用,即时该类不是public的。
48、有final修饰的数据属于编译期常量,必须在域的定义处或每个构造器中用表达式对final进行赋值。final用在基本数据类型上,保证其值不变,当对用final修饰对象时,它保证的是该引用恒定不变,一旦引用被初始化指向了一个对象,就无法再把它改为指向另一个对象。类中所有的private方法都隐式地指定为是final的
49、类的加载通常发生于创建类的第一个对象时,但是当访问static域或static方法时,也会发生加载(构造器也是static方法,尽管static关键字并没有显式地写出来。)
50、绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定。
1)静态绑定:在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定。
2)后期绑定:在运行时根据具体对象的类型进行绑定。在java中,几乎所有的方法都是后期绑定的。
51、一个复杂对象调用构造器要遵照以下顺序:
1)调用父类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层子类,等等,直到最低层的导出类。
2)按照声明顺序调用成员的初始化方法。
3)调用子类构造器的主体。

    推荐阅读