一. 方法的定义, 方法有哪些调用方式?
概念: 方法是若干语句的功能集合, 方法的定义是不能够直接使用的, 如果使用, 要在main方法中调用
格式: 修饰符(public static)返回值类型 方法名称(参数类型 参数名称, ...) { 方法体; return 返回值; }
修饰符: 现阶段的固定写法 public static
返回值类型: 也就是方法最终产生的数据结果是什么类型
方法名称: 方法的名字, 规则和变量一样, 小驼峰(首写字母小写 其余大写)
参数类型: 进入方法的数据是什么类型
参数名称: 进入方法的数据对应的变量名称(参数如果有多个 用逗号分隔)
方法体: 方法需要做的事情, 若干行代码
返回值: 方法执行后最终产生的数据结果
return两个作用:
1. 停止当前方法;
2. 将后面的结果返回给调用处;
方法定义的注意事项:
1. 方法定义的先后顺序无所谓
2. 方法定义必须是挨着的, 不能在一个方法的内部定义另一个方法
3. 方法定义之后不会执行, 如果希望执行, 一定要调用: 单独调用, 打印调用, 赋值调用
4. 如果方法有返回值, 则必须写上 "return返回值;", 不能没有
5. return后面的返回值数据, 必须和方法的返回值类型对应起来
6. 对于一个void没有返回值的方法, 不能写return后面的返回值, 只能写return自己
7. 对于void方法中最后一行的return可以省略不写
8. 一个方法当中可以有多个return语句, 但是必须保证同时只有一个return被执行, 两个return不能同时连写
定义一个方法的三要素: 返回值类型; 方法名称; 参数列表
方法调用的四个步骤:
1. 找到方法
2. 参数船体
3. 执行方法体
4. 带着返回值回到方法的调用处
方法的三种调用格式:
1. 单独调用: 方法名称(参数); 没有打印没有赋值, 只是让方法调用
2. 打印调用: System.out.println(方法名称(参数)); 把方法调用写到输出语句, return后面的结果可以打印
3. 赋值调用: 数据类型 变量名称 = 方法名称(参数); 将结果赋值给变量, 变量可以进行别的操作
方法小括号中有参数和无参数:
有参数: 小括号当中有内容, 当一个方法需要一些数据条件, 才能完成任务的时候, 就是有参数, 例如: 两个数相加, 需要知道两个数字格式多少, 才能相加
无参数: 小括号当中留空, 一个方法不需要任何数据条件, 自己能够独立完成任务, 就是无参数, 例如定义一个方法, 打印固定10次hello
对比方法有返回值和无返回值:
注意事项: 对于有返回值的方法, 可以使用单独调用, 打印调用或者赋值调用. 但是对于无返回值的方法, 只能使用单独调用, 不能使用打印调用或者赋值调用
二. 参数的数据类型可以使哪些, 参数的分类有哪些?
1. Java数据类型基本概念:
Java是强类型语言, 数据类型是语言中最基本的单元定义, 本质上可以分为两种: 基本类型和引用数据类型.
2. 基本数据类型(4类8种: 整数型, 浮点型, 字符型, 布尔型):
byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值0int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0long:长整型,在内存中占64位,即8个字节-2^63~2^63-1,默认值0Lfloat:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false3. 引用类型:引用类型指向一个对象, 指向对象的变量是引用变量, 这些变量在声明时被指定为一个特定的类型, 变量一旦声明后, 类型就不能改变了.所有引用类型的默认值都是null. 引用类型变量在声明后必须通过实例化开辟数据空间, 才能对变量所指向的对象进行访问.
三. 数组的定义,数组与集合的区别及联系?
概念: 数组是指一组数据的集合, 数组中的每个数据被称为元素. 在数组中可以存放任意类型的元素, 但同一个数组里存放的元素类型必须一致
数组的定义:
格式: 数据类型[] 数组名 = new 数据类型[元素个数或数组长度];
注意事项: 数组中最小的索引是0, 最大的索引是"数组的长度 - 1";
数组的初始化:
1. 动态初始化: 在定义数组时只指定数组的长度, 由系统自动为元素赋初值的方式成为动态初始化.
2. 静态初始化: 在定义数组的同时为数组的每个元素赋值. 静态初始化有两种方式:
1. 类型[] 数组名 = new 类型[]{ 元素, 元素, ... };
2. 类型[] 数组名 = { 元素, 元素, 元素, ... } //为了简便, 建议使用第二种方式
数组Array和集合的区别:
1. 数组是大小固定的, 并且同一个数组只能存放类型一样的数据(基本类型/引用类型)
2. Java集合可以存储和操作数目不固定的一组数据
3. 若程序执行时不知道需要多少对象,需要在空间不足时自动扩增容量, 则需要使用容器类库, array不适用
数组Array和集合的联系:
* 使用相应的toArray()和Arrays.asList()方法可以互相转换
四. 静态的定义,特点,注意事项,优缺点?
在了解某样东西的时候我们通常会从它是什么,为什么,和怎么样在三方面来衡量,对于java中的static,我们也这样讨论下,要明确以下几点:
1、 static在java中到底代表什么,为何要用它?
2、 static在java中怎么用?
3、 static 有那些特点和使用的“局限”?
4、当成员变量被静态修饰后,和非静态成员变量的区别?
1、 static在java中到底代表什么,为何要用它?
static――静态――“指定位置“
首先,我们来看看java的内存:java把内存分为栈内存和堆内存,栈内存用来存放一些基本类型的变量和数组及对象的引用变量,而堆内存主要是来放置对象的。
用 static的修饰的变量和方法,实际上是指定了这些变量和方法在内存中的“固定位置”-static storage。既然要有“固定位置”那么他们的 “大小”似乎就是固定的了,有了固定位置和固定大小的特征了,在栈中或堆中开辟空间那就是非常的方便了。如果静态的变量或方法在不出其作用域的情况下,其引用句柄是不会发生改变的。
我们常看到:static变量有点类似于C中的全局变量的概念;静态表示的是内存的共享,就是它的每一个 实例都指向同一个内存地址。把static拿来,就是告诉JVM它是静态的,它的引用(含间接引用)都是指向同一个位置,在那个地方,你把它改了,它就不会变成原样,你把它清理了,它就不会回来了。
注:java的主类中main()方法本身就是一个static的,所以main方法的执行就是在没有产生新的实例的情况。
2、 static在java中怎么用?
static是一个修饰符,用于修饰成员(成员变量和成员函数)。
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用:类名.静态成员。
3、 static 有那些特点和使用的“局限”?
(一)特点:
1.静态成员随着类的加载而加载;
2.静态成员优先于对象存在;
3.静态成员被所有对象所共享;
4.静态成员多了一个中调用方式,可以被类名直接调用。
(二)利弊:
利:
对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份;
可以直接被类名调用。
弊:
生命周期过长;
访问出现局限性,只能访问静态。
(三)注意事项:
1.静态方法只能访问静态成员, 非静态方法既可以访问静态又可以访问非静态;
2.静态方法中不可以定义this,super关键字;(因为this代表是对象,而静态存在时,有可能没有对象,且静态优先于对象存在。所以静态方法运行时,this是没有任何对象代表的。 简单说,先进内存的数据不可以访问后进内存的数据,可是后进内存数据可以访问先进内存的数据)
3.主函数是静态的
4、当成员变量被静态修饰后,和非静态成员变量的区别?
1.调用不同
静态变量也称为类变量,也就是直接可以被类名调用的变量,这个变量是所属于类的;
非静态变量称为成员变量,或者实例变量,是被对象调用的,是所属具体对象的。
2. 生命周期不同
静态变量随着类的加载而加载,也意味着随着类的消失而消失,生命周期最长;
实例变量,随着对象的创建而加载,随着对象的消失而消失,按照对象的生命周期而存在。
3. 内存位置不同
静态变量存储在方法区的静态区中;
实例变量存在于对象所属的堆内存中。
4. 所属不同:
静态变量数据,被所有对象所共享;
实例变量是对象中的特有数据。
五. 代码块的分类及每种代码块的特点?
1. 概念:
代码是程序的表现,而代码块是代码的具体组成部分。在java中,我们将用{ }括起来的块成为代码块,代码块分为以下四种。
2. 普通代码块:
定义在方法中不加任何修饰符的代码块称为普通代码块。普通代码块使用较少,一般如果方法中的代码过长,为避免变量重名,可使用普通代码块进行解决,如下:
public static void main(String[] args) {
// 直接使用{}定义,普通方法块
{
int x = 10 ;
System.out.println("x = " +x);
}
int x = 100 ;
System.out.println("x = " +x);
}
9
9
1
public static void main(String[] args) {
2
// 直接使用{}定义,普通方法块
3
{
4
int x = 10 ;
5
System.out.println("x = " +x);
6
}
7
int x = 100 ;
8
System.out.println("x = " +x);
9
}
3. 构造代码块:
定义在类中不加任何修饰(无修饰符)的代码块称为构造块。构造块优先构造方法执行,每创建一个对象,构造块就执行一次。主类中也有构造块,而且主类的构造代码块也是在主类构造方法之前执行的(主类也有构造方法,如果没有显示的写出,那么就是JVM提供的默认无参构造)。
构造代码块中可以执行简单的逻辑操作,使我们在执行构造方法之前能做些什么事情,如打印日志之类的。
//直接在类中定义的没有加static关键字的代码块{}称为构造代码块,例子程序如下:
public class CodeDemo02{
public CodeDemo02(){
System.out.println("========这是构造方法=========");
}
//这是构造代码块,而且在new对象时,构造代码块优先构造方法执行
{
System.out.println("=========这是构造块!=========");
}
public static void main(String[] args){
new CodeDemo02();
new CodeDemo02();
}
}
15
15
1
//直接在类中定义的没有加static关键字的代码块{}称为构造代码块,例子程序如下:
2
public class CodeDemo02{
3
public CodeDemo02(){
4
System.out.println("========这是构造方法=========");
5
}
6
//这是构造代码块,而且在new对象时,构造代码块优先构造方法执行
7
8
{
9
System.out.println("=========这是构造块!=========");
10
}
11
public static void main(String[] args){
12
new CodeDemo02();
13
new CodeDemo02();
14
}
15
}
4. 静态代码块:
静态块优先于构造块执行,并且不管创建多少个对象都只在第一次创建该类对象的时候执行一次。
主类中也存在静态块,且主类中的静态块优先于main方法执行。
针对静态块以上的优点,如果有一些属性需要在对象创建开始就进行处理,可以考虑放在静态块中执行。
// 使用static关键字声明的代码块称为静态代码块,静态块的主要目的是用来为静态属性初始化,例子程序如下:
public class CodeDemo03 {
static{
System.out.println("这是主类中的静态代码块!");
}
public static void main(String[] args){
new Demo();
new Demo();
new Demo();
}
}
class Demo {
static{
System.out.println("这是Demo类中的静态代码块!");
}
{
System.out.println("这是Demo类中的构造块!");
}
public Demo(){
System.out.println("这是构造方法!");
}
}
//静态块优先于主方法的执行,静态块优先于构造方法的执行,而且只执行一次!
25
25
1
// 使用static关键字声明的代码块称为静态代码块,静态块的主要目的是用来为静态属性初始化,例子程序如下:
2
public class CodeDemo03 {
3
static{
4
System.out.println("这是主类中的静态代码块!");
5
}
6
public static void main(String[] args){
7
new Demo();
8
new Demo();
9
new Demo();
10
}
11
}
12
13
class Demo {
14
15
static{
16
System.out.println("这是Demo类中的静态代码块!");
17
}
18
{
19
System.out.println("这是Demo类中的构造块!");
20
}
21
public Demo(){
22
System.out.println("这是构造方法!");
23
}
24
}
25
//静态块优先于主方法的执行,静态块优先于构造方法的执行,而且只执行一次!
5. 同步代码块:
同步代码块指的是被同步修饰符synchronized的代码块,用于将进入代码块的指定对象上锁,在上锁对象运行同步代码块期间,处于互斥状态。
// 同步代码块主要出现在多线程中。例如:
class SellThread implements Runnable{
int ticket = 100;
Object obj = new Object();
public void run(){
while(true){
synchronized(obj){
if(ticket > 0){
ticket--;
}
}
}
}
}
15
15
1
// 同步代码块主要出现在多线程中。例如:
2
class SellThread implements Runnable{
3
int ticket = 100;
4
Object obj = new Object();
5
public void run(){
6
while(true){
7
synchronized(obj){
8
if(ticket > 0){
9
ticket--;
10
}
11
}
12
}
13
}
14
15
}
六. 继承的概述,继承的特点,继承中成员变量的特点?
1. 继承的基本概念:
1.继承是面向对象的三大特性之一。(封装,继承,多态)
2.被继承的类是父类,继承父类的类是子类
3.继承可以使一个对象直接使用另以对象的属性和方法
4.继承可实现代码重用
2. 特点:
1.基类中的方法使用private修饰,就代表该方法仅属于该类,不会被子类继承,调用和重写。
2.基类方法使用final修饰代表此方法不会被子类所重写。
3.使用@Override注解表示重写父类方法,来区分重载父类方法。
4.父类中的变量通常设为private,操作变量的方法设为protected,以此来控制变量的访问权限问题。
5.向上转型
6.Java中类只支持单继承
7.Java中可以多层(重)继承(继承体系)
3. 继承中成员变量的特点:
1.子类继承了父类,父类中有私有变量,但是子类访问不了父类的私有变量。
2.子父类中有相同名称的成员变量,则依照就近原则,用子类的成员变量
3.子父类中有不同名称的成员变量,则使用父类中的成员变量
4.如果有局部变量就是用局部变量
super:可以访问父类的成员
this:引用当前对象
4. 继承的优点和缺点:
优点:
提高了代码的复用性
提高了代码的维护性
让类与类产生了一个关系,是多态的前提
缺点:
A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
原则:低耦合,高内聚。
耦合:类与类的关系
内聚:自己完成某件事情的能力
B:打破了封装性
5. 继承的注意事项:
1.子类不能继承父类的私有成员
2.子类不能继承父类的构造方法,但是可以通过super去访问
3.不要为了部分功能而去继承
七. 继承中成员方法的特点,方法重写的应用场景和注意事项?
1. 继承中成员方法的特点:
1. 子类中没有这个方法,调用父类的
2. 子类中重写了这个方法,调用子类的
2. 方法重写和方法重载:
方法的重写:在子父类当中,子类的方法和父类的完全一样,子类重写了父类的方法(覆盖),当子类重写了父类的方法之后,使用子类对象调用的就是子类的方法
方法的重载:在一个类中,有多个重名的方法,但是其参数不一样(参数的个数,参数的类型,参数的顺序),和返回值无关
3. 方法重写的应用场景和注意事项?
* 方法重写的应用场景:当父类的方法不能完全满足子类使用的时候,既可以保留父类的功能(沿袭、传承),还可以有自己特有的功能
* 方法重写的注意事项:
1. 不可以重写父类私有的成员方法,压根就看不到父类的私有成员
2. 子类重写父类方法,权限必须大于等于父类方法的权限
八. this和super的区别,继承中构造方法的执行顺序?
1. this和super的区别:
* this:当前对象的引用
1. 调用子类的成员变量
2. 调用子类的成员方法
3. 在子类的构造方法第一行调用子类其他构造方法
* super:子类对象的父类引用
1. 调用父类的成员变量
2. 调用父类的成员方法
3. 在子类的构造方法第一行调用父类的构造方法
2. 继承中构造方法的执行顺序:
A:super(实参列表);语句在子类的构造方法中使用,用来调用父类中的构造方法(具体哪一个由传递的参数决定),并且只能在构造方法的第一行使用
B:this(实参列表); 语句在类的构造方法中使用,用来调用本类中的其它构造方法(具体哪一个由传递的参数决定),并且只能在构造方法的第一行使用
3. 继承中的成员关系:
A:成员变量
a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单。
b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢?
* 子类的方法访问变量的查找顺序:
1.在子类方法的局部范围找,有就使用。
2.在子类的成员范围找,有就使用。
3.在父类的成员范围找,有就使用。
4.找不到,就报错。
B:构造方法
a:子类的构造方法默认会去访问父类的无参构造方法是为了子类访问父类数据的初始化。
b:父类中如果没有无参构造方法,怎么办?
1.子类通过super去明确调用带参构造。
2.子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造。
3.让父类提供无参构造。
C:成员方法
a:子类的成员方法和父类中的成员方法名称不一样,这个太简单
b:子类的成员方法和父类中的成员方法名称一样,这个怎么访问呢?
* 通过子类对象访问一个方法的查找顺序:
1.在子类中找,有就使用
2.在父类中找,有就使用
3.找不到,就报错
4. 总结:
1.类中的静态对象先于static{}执行
2.static{}中的代码是在构建类对象之前执行的
3.构造子类的时候是按照先父后子的顺序执行的
4.如果在子的构造函数中并没有使用显式的调用父类的构造函数(使用super),则执行无参构造函数。
5.如果使用this(),则会先调用this(),再调用下面的代码(此时父类别的默认构造函数不再执行,而会根据执行this()执行相应的父构造函数)
九. final关键字,被final修饰的成员都有什么特点?
1. 概念:
final是Java中的一个保留关键字,它可以标记在成员变量、方法、类以及本地变量上。一旦我们将某个对象声明为了final的,那么我们将不能再改变这个对象的引用了。如果我们尝试将被修饰为final的对象重新赋值,编译器就会报错
2. 用法:
1.修饰变量
* final修饰在成员变量或者局部变量上,那么我们可以称这个变量是final变量
如果我们将被final修饰的变量重新赋值,编译器就会报出如图:cannot assign a value to final variable.(不能给final变量赋值)虽然我们不能改变对象的引用,但是我们仍旧可以set对象的属性。
2.修饰方法
* 被final所修饰的方法将无法被子类重写。
“使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。” -- 摘自《Java编程思想》
注:类的private方法会隐式地被指定为final方法。
3.修饰类
* 如果某个类被final所修饰,那么表明这个的功能通常是完整的;该类将不能被继承。并且final类的所有方法都会被隐式的修饰成final
4.匿名类中的所有变量都必须是final的。
3. 好处:
1. final关键字提高了性能。JVM和Java应用都会缓存final变量。
2. final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
3. 使用final关键字,JVM会对方法、变量及类进行优化。
4. 对于不可变类,它的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销。