scjp随笔1

第一章

  1. 标识符和JavaBean
    和大多数的语言一样,标识符由字母、数字和下划线组成,第一个字符不能为数字。
    Javabean的标准参考阿里巴巴开发手册,变量和方法的命名要有自说明功能,对于实例变量,使用标准的setter和getter
  2. 声明类
    一个.java文件只能有一个public类且与.java文件同名,一个.java文件可以有多个类,类声明形式:class Xxx{}
  3. 声明接口
    创建一个接口,是在定义一份契约,除非这个类是抽象类,否则所有实现该接口的类都需要实现这些契约,一个类可以实现多个接口,一个接口也可以继承多个接口,(jdk1.6)接口中只能含有抽象方法,声明的变量也是常量并且都是默认是、只能是public的(常量默认被static final修饰)。接口声明:
interface Xxx{}
  1. 声明类成员
    通常我们将方法和实例变量(非局部的)统称为成员,方法常称为实例方法。
    1)访问控制
    可以将类当作一个细小的系统,而系统通常有用户,不同的用户有不同的权限,系统通过账号来识别权限,而类是通过访问修饰符实现。对于一个类来讲,如果它对其使用者而言是不可见的,即无法谈论操作类的内部,就像这个系统你见都见不到怎么登陆?
    访问修饰符有:public、protected、private。无访问修饰符,则为包权限,包权限和protected很像,只有在继承关系中才能有所区别。其中的区别:
public:被修饰的方法、实例变量所有类都是访问
private:被修饰的方法、实例变量只能在该类内部进行访问
protected:被修饰的方法、实例变量可以在类内部访问,同时也能被子类访问
包权限:可以将包理解为目录,方法、实例变量可以在类内部访问,同时也能被子类访问,除此之外在同一个目录下的类也能进行进行访问。

上面所说的有点抽象,尤其是包权限,可以这么想象,有两个类,其中一个为

public class A{
	int age;//没有修饰符,所以为包权限
}

另一个

public class B{
	public static void main(String[] args){
		A a = new A();
		System.out.println(a.age); //这个可以进行访问吗?
	} 
}

假如A、B的目录结构如下,可以访问

-packageXxx
	-A
	-B

下面则否

-packageXxx1
	-A
-packageXxx2
	-B

2)包权限和protected的区分要记

//包结构:
-packageXxx1
	-A
-packageXxx2
	-B
public class A{
	int age;//没有修饰符,所以为包权限
}
public class B extends A{
	public static void main(String[] args){
		System.out.println(age);//没有问题
		A a = new A();
		System.out.println(a.age); //此处编译报错
	} 
}

看到这里大概能稍微理解他们的区别了,age虽然是包权限,但是为什么可以在不同包下被B访问呢,因为其不是通过简单的.访问,而是通过继承(所以对于“访问权限”这一词而言,描述的是简单访问的权限),如果使用protected修饰age,则上述没有问题。
3)声明枚举
枚举可以看成是已经规定好内容的类,基本构成是常量,这些常量代表的含义类似。

第二章 面向对象

  1. 封装
    封装是一种抽象的概念,目的是为了实现类的单一职责,从而实现松耦合和高内聚,以方便程序的维护。
  2. 继承和多态
    window操作系统中有用户的概念,其职责是用于控制用户对操作系统操作权限。每一个用户的操作权限是可以不同的,但绝大部分的权限一样,如果没建立一个用户都需要为其分配一次权限(数百个多选框摆在你面前),那将是痛苦的,所以用户组这一概念产生,用于管理一组拥有类似权限的用户,这样一来,在创建一个用户时,将其放置在对象用户组即可。其中继承的概念与此时相似的,只是继承复用的时代码。
    通常我们将某个用户归属与某个用户组时,例如权限管理员和系统管理员组,就会说权限管理员是系统管理员,这就是继承中的IS-A测试,只有通过IS-A测试的Java对象才可以谈论多态。这个可以类比文件管理员和权限管理员,系统管理员组提供了组员可以操作文件的能力,他们都可以对文件进行操作,但是操作时由于权限的不同,系统执行的结果就会不同,例如权限管理员要删除文件,系统会拒绝,文件管理员则可以删除。
  3. 重写和重载
    因为通过IS-A测试的父类引用可以引用子类的对象,不同子类内部的实现细节可以不同,所以会出现同一个引用,调用同一个方法,但是产生不同结果的现象,这个现象称为多态。在父子类间实现多态的方式是通过方法重写,即子类重写父类方法。而在单个类中实现多态的方式是方法重载。
    1)方法重写
    即子类覆盖父类的方法实现,所以覆盖的方法必须和原来的名称、参数列表和返回值一样(通过IS-A测试)。但是其不能被final、static修饰,并且其访问权限不能比父类的严格、抛出的异常不能比父类的宽泛(只能更少更精确,但是如果父类没有抛出异常,这个不做限制)。
    2)方法重载
    在一个类中有两个或多个方法的名称一样,但是方法的参数列表不同,这个不同体现在参数的类型(对应的位置)、参数的个数。每一个重载的方法可以当作是一个新的方法,所以没有方法重写那么多条条框框。
方法重写实现的是运行时的多态,方法重载实现的是编译时的多态
  1. 合法的返回值
    需要重点记住的是子类在重写父类方法时,覆盖方法的返回值只要通过IS-A测试就是合法的
  2. 构造函数和实例化
    1)构造函数
    在编写一个类时,如果没有显示的为类提供一个构造函数,则在编译时,jvm会提供一个默认的构造函数;如果提供了构造函数(无论何种形式),jvm不再提供默认构造函数,默认构造函数如:
class Xxx{
	//默认构造器,无参的
	Xxx(){
	}
}

容易造成的误区是当你仅定义了一个有参构造器后认为还能使用

Xxx x = new Xxx();//编译报错

2)实例化
一个类在进行实例前,会先实例化其超类,通常是通过一个隐式的super();进行调用父类构造器的。实例化过程有简单的也有复杂的,在夹杂静态代码块和初始化块的情况下,实例化变得复杂,它们的流程如下:

首先我们要知道一点:
静态代码块在类加载时便会执行,即其只执行一次;
初始化代码块在构造器执行前执行,即每次实例化都会执行一次。
实例化时类的加载顺序上,父类优先于子类。

执行顺序:
父类静态代码块->子类静态代码块->父类初始化块->父类构造器->
子类初始化块->子类构造器->构造完成
  1. 静态成员
    静态成员是属于类的,由所有该类的实例共享,使用静态变量时需要对变量进行初始化,静态方法中不能调用非静态的方法和变量

第三章 赋值

  1. 前提知识
    实例变量和对象是驻留在堆上的,局部变量驻留在栈上。
    每调用一个方法,该方法就会入栈,方法调用结束时就出出战。
    在方法入栈期间生成的局部变量和引用在方法出栈后而被清除。
  2. 静态变量、实例变量与局部变量的赋值
  • 静态变量在使用前必须被初始化
  • 实例变量如果没有被显示的初始化,则会为其分配默认值
  • 局部变量没有初始化,在保证不使用它的前提下,编译不会报错,如果使用未初始化的局部变量编译将会报错。局部引用同理,并不会为一个未初始化的引用主动分配一个null值,所以将会出现
Xxx xxx;
if(xxx == null) {// 编译报错
	System.out.println();
}
  1. 向方法传递变量
    在Java中,无论向方法传递的是基本类型变量还是引用类型变量,都是使用值传递的方式。
  • 对于基本类型变量,会对变量值进行拷贝,方法形参获得的是实参的一个副本,所以在方法上修改,并不影响方法外的;
  • 对于引用类型变量,向方法形参传递的是实参的位模式副本,而位模式可以理解为保存着寻找实际对象的方法,所以在方法上对使用形参进行操作,实际上是对同一个对象进行操作(因为寻找对象的方法一样,所以找到的对象相同),故而会影响方法外的对象。
  1. 包装类和拆装箱
  • 包装类的出现
    因为基本类型变量本身提供的操作有限,而我们通常会频繁的对基本类型进行转换,这些工作如果全部手动完成,将会非常影响效率。所以jvm提供了包装类,并且提供了一种基本类型与包装类型间相互转换的机制(自动拆装箱机制),而这些包装类提供了许多功能,大大简化了数据的处理过程。
  • 基本类型与之对应的包装类型
基本类型		包装类型
int			Integer
short		Short
long		Long
char		Character
byte		Byte
boolean		Boolean
float		Float
double		Double
  • 拆装箱示例
Integer x = 1; //自动装箱
int y = x; // 自动拆箱
  1. 重载
  • 导致重载难于处理的3个因素:
    • 加宽(对于基本类型变量,存在隐式转换,转换后表示的范围为更加宽泛)
  byte y = 5;
  int x = y; //y隐式转换为int
- 自动装箱
- var-arg
  • 加宽和装箱单独使用下的规则
    5.1 加宽先于装箱、var-arg执行,加宽遵循最小范围的加宽
static void go(Integer x){
	System.out.println("int");
}
static void go(long x){//此处是long而不是Long
	System.out.println("long");
}
public static void main(String[] args){
	int x = 5;
	go(x); //此处输出的是long
}
static void go(int x, int y){
	System.out.println("int int");
}
static void go(byte... x){
	System.out.println("byte...");
}
public static void main(String[] args){
	byte x = 5;
	go(x, x); //此处输出的是int int
}

5.2 装箱先于var-arg执行

static void go(Byte x, Byte y){
	System.out.println("Byte Byte");
}
static void go(byte... x){
	System.out.println("byte...");
}
public static void main(String[] args){
	byte x = 5;
	go(x, x); //此处输出的是Byte Byte
}

5.3 引用变量的加宽,只要通过IS-A测试,则可以加宽

  • 加宽和装箱组合使用下的规则
    • 先装箱
    • 再加宽,能否加宽成功,取决于IS-A测试
    • 可以组合使用var-agr与加宽或装箱
static void wide_vararg(long... x){
	System.out.println("long...");
}
static void box_vararg(Integer... x){
	System.out.println("Integer...");
}
public static void main(String[] args){
	int x = 5;
	wide_vararg(x, x); // 输出long...
	box_vararg(x, x); // 输出Inetger...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值