由于之前是看书学习java,真正学到java面向对象的时候,才开始看毕向东老师的视频,觉得轻松愉快,甚至有些兴奋和幸福。因为我找到了java的乐趣所在。
为什么还要返回来总结这些看似简单的知识点呢?要正视这个问题,首先有一点,确实是为了总结而总结,这点私心还是存在的。但是学java,我深刻明白不是为了学习而学习的。返回来总结的另一个重要的原因,就是巩固知识点,别看这些小知识点,却蕴含着大智慧,就拿下面这个程序来说吧,这里就涉及到了一个类型转换的问题(文章中会提到的)。而且,我发现,现在返过来总结这些知识点,可以让自己学到更多的知识,我会首先将后面讲到的关于这些知识点的问题补充过来,还能通过网上查找到一些资料,融入到自己的知识中来,并添加进来,这样,对看我文章的人,和我自己都有额外的收获。好,开始整理:
一、基本概念概述
1、关键字:
被java赋予了特殊含义的单词。总结如下:
1、类型定义符关键字:
整数类型:byte,short,int,long 浮点类型:float、double
字符类型:char 布尔类型:boolean
2、循环判断修饰符关键字:
表判断:if、else、else if;switch、case;
表循环:for,while、do while;
表继续:continue;表结束:break;
3、访问权限修饰符关键字:
私有的:private;受保护的:protected;公有的:public。
修饰符间的比较见后面文章的总结。
4、类、函数、变量修饰符关键字:
抽象的:abstract;最终的:final;静态的:static;同步的:synchronized;枚举类:enum。
5、类与类间关系的关键字
继承的:extends;实现的:implements。
6、实例的建立、引用及判断的关键字:
创建:new;当前引用:this;父类引用:super;判断所属:instanceof。
7、异常处理的关键字:
尝试(检查异常):try; 捕获(异常):捕获异常; 最终(一定执行):finally;
抛出(异常对象):throw; 抛出(异常):throws。
8、包关键字:
包:package;导入(包)import。
9、其他修饰符关键字(现在不做重点说明,以及java保留关键字不再阐述):
native:定义本地方法;
strictfp:即strict float point,精确浮点;
transient:变量修饰符,用它声明一个实例变量,当对象存储时,它的值不需要维持。
volatile:类型修饰符,用来修饰被不同线程访问和修改的变量。
assert:断言,作为异常处理的一种高级形式,在测试代码运行时使用。
2、标识符:
1、定义:程序中自定义的一些名称。如类名
2、命名规则:
a.由26个英文字符大小写,数字0-9,符号中的_和$,组成。
b.数字不可以开头,不可以使用关键字
c.严格区分大小写,起名为了提高阅读性,尽量使用有意义的名字
3、名称规范:
a.包名:多单词组成是全部为小写字母。如:packageperson
b.类名和接口名:首个单词大写,多个单词组成时,后面的每个单词首字母大写。如:StringDemo
c.变量名和函数名: 首个单词小写,多个单词组成时,后面的每个单词首字母大写。如:functionTest
d.常量名:所有字母都大写。多个单词组成时,用下划线(“_”)连接。如MAX_VALUE
3、变量:
1、概述:将不确定的数据进行存储,会在内存中开辟一块空间,存放在栈内存中。每一个变量都隶属于一种类型。它代表着一个值,便于在语句中灵活使用,且比具体值更有意义。
2、声明变量:a.数据类型 变量名; b.数据类型 变量名 = 初始化值;
3、变量初始化:对于上面的a,系统默认初始化值,也称隐式初始化。对于b,是显式初始化值。
默认初始化值:
数值类型:byte、short、int :0 ; long:0L; float:0.0f; double:0.0d
字符类型:char:''(空字符,打印时无显示)
布尔类型:boolean:false
引用型默认初始化值为null。
4、常量:
在java中,使用final声明常量,变量名要全部大写。
如:
public static final double PI = 3.1415926;
需要注意的是:
a.声明变量并赋初值后,这个值就不能再更改了。
b.类常量的声明位于main方法的外部,或无main函数的类的全局中的位置。这样,可以在同一个类中的其他地方使用这个常量。
c.上面默认初始化的那些值皆为常量值。
二、数据类型
java中的数据类型分为基本数据类型和引用数据类型(后面会具体体现,这里主要讲基本数据类型)。他们的共性之处在于,都是存在于栈内存中的。但是基本数据类型和引用数据类型在内存中的本质是有区别的,基本数据类型本身的值就是在栈内存中的,无需引用任何数据,自己管自己的。但是引用数据类型则不一样,它在栈内存中也有值,只不过这值是地址值,拿的别人的东西。下面我就简单总结一下关于基本数据类型。
先来看一个小程序:
class JavaDemo
{
public static void main(String [] args)
{
int i = 5;
float f = 6.5f;
double d = i + f;
System.out.println("打印d为:" + d);//结果为:打印d为11.5
}
}
通过这个小程序,我们来主要说一下关于数据类型的问题。
1、基本数据类型:
上面程序中提到的int、float、double等是数据类型中的几种。这些都属于基本数据类型。对于基本数据类型,上面也说到了,是自己的值存放在栈内存中。对于基本数据类型,主要有八种,分别为:
1、整数类型:
byte: 字节型 -------> 1字节,取值范围:(-2E7 ~ 2E7 - 1)-128 ~ 127
short:短整型 -------> 2字节,取值范围:(-2E15 ~ 2E15 - 1)-32768 ~ 32767
int: 整型 -------> 4字节,取值范围:(-2E31 ~ 2E31 - 1)-2147483648 ~ 214748367 ---超过20亿
long: 长整型 -------> 8字节,取值范围:(-2E61 ~ 2E61 - 1)-9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807
2、浮点型:
float: 单精度浮点型 -------> 4字节,取值范围:大约± 3.402 823 47E + 38F(有效位6 ~ 7位)
double:双精度浮点型 -------> 8字节,取值范围:大约± 1.797 693 134 862 315 70E + 308(有效位15位)
3、字符型:
char:字符型 ------->用于表示单个字符。如‘A’。
4、布尔型:
boolean:布尔型 ------->表示逻辑判断条件,有两个值为true和false。
2、基本数据类型说明:
1、int类型:在整数类型中,对数据进行赋值的时候,默认是int类型的,就是说,可以直接使用任何整型数据,基本上是作为int使用的。大数值单说。
2、double类型:在浮点型类型中,和int相似,默认的是double类型的。
3、char类型:每一个字符都对应一个ASCll码,如'A'对应着65,'a'对应着97。
public static void main(String[] args) {
char ch1 = 97;
char ch2 = 'a';
System.out.println("ch1 = " + ch1); //ch1 = a
System.out.println("ch2 = " + ch2); //ch2 = a
}
4、对于基本数据类型,在进行参数传递时,是进行的值传递。
5、基本数据类型的初始化:
整型默认初始化为: 0 字符型默认初始化为:null
浮点型默认初始化为: 0.0(f) 布尔型默认初始化为:false
3、关于基本类型转化与提升问题
1、自动类型转换:
也称为隐式类型转化。当一个“小”(指范围小)数据与“大”数据进行运算时,java默认会向“大”数据方向转换,然后再运算,如上面的程序中的运算,就是讲i = 5转为i = 5.0在和f进行运算,然后再提升为double类型。
注:
a.所有byte、short、char类型的值将提升为int类型。
b.自动类型转换关系:byte -->short(char) -->int -->long -->float -->double
2、强制类型转换:
和自动转换类型相反,格式:int i = (int)6.53;,就是将“大”数据强转为“小”数据。
注:
a.会损失精度,如6.53转完后为6,会将小数点后的值去除,只保留整数位。
b.强制类型转换关系:double -->float -->long -->int -->short(char) -->byte
c.对于int m = (int)'a';//结果为97,因为a在ASCll码中的值为97。
4、关于证书数据大小溢出的问题
当整数的数据大小超出了可以表示的范围,而程序中又没有做数值范围的检查时,这个整型变量所输出的值将发生紊乱,且不是预期的运行结果。
public static void main(String[] args) {
int x = Integer.MAX_VALUE;
System.out.println("x = " + x); //x = 2147483647
System.out.println("x+1 = " + (x + 1)); //x+1 = -2147483648
System.out.println("x+2 = " + (x + 2)); //x+2 = -2147483647
System.out.println("x + 2 = "+(x+2L)); //x + 2 = 2147483649
System.out.println("x + 3 = "+((long)x+3)); //x + 3 = 2147483650
}
类似于计数器的内容到最大值时会自动归零。
通过显式指明数据类型,避免溢出:
· 在表达式的常量部分加上L
· 利用强制类型转换的方式
· 对于long类型的溢出,就没有办法处理了,就需要在程序中加上变量值的界限检查。
三、运算符
1、概述:
数据的存储不仅仅只为了存,更多的是运算,那么该如何对这些数据进行运算呢?先说一说基本的运算符及运算。
2、运算符:
1、算数运算符
正号:+ 负号:-
加法:+ 减法:- 乘法:* 除法:/ 取模:%
自增:++,即自加1,可至于前或后;如:++a(a先自增,然后再和a相加),a++(先和a相加,a再自增)
自减:- -,即自减1, 可至于前或后;如:- -a(a先自减,然后再和a相减),a- -(先和a相减,a再自减)
字符串相连:+
2、赋值运算符:=、+=、-=、*=、/=、%=等
如:
s += 5
,就是将s的值和5相加再赋值给s。但是这种运算和s = s + 5;是有区别的。
s += 5
有自我提升的功能,而 s = s + 5;可能就会编译失败。比如,s为short型的值,对于后者那么编译时就会报错:可能损失精度。对于前者,会将5强转为short型,在与s的值相加,然后再赋值给s。
3、比较运算符:==、!=、< 、> 、<= 、>= 、instanceof
结果均为boolean型,即所得的值为true或者false
如:
5 == 3
为false
;5 != 3
为true
4、逻辑运算符:&、|、^、!、&&、||
与: &; 如:true & false 为false;
或:|; 如:true | false为true;
非: !; 如: ! true 为false
异或: ^; 如:true ^ false 为true(真异或真为假)
短路:&&:只要有一边为false,结果则为false
||:只要有一边为true,结果则为true
5、位运算:<< 、>> 、>>> 、 &、|、^ 、~;在二进制水平上运算
左移:<<;3 << 2 = 12 ---->322=12
右移:>>;3 >> 1 = 1 ---->3/2 =1
无符号右移:>>>; 3 >>> 1 = 1 ---->3/2 =1
与: &;6 & 3 = 2
或:|;6 | 3 = 7
异或: ^;6 ^ 3 = 5。一个数以后两次相同点数,那么结果还为本身。在加密和解密中有应用。
:反码: 6 = -7,其实就是对当前数的二进制的取反。
注:
a.对于>>,最高位补什么由原有数据的最高位值而定,若最高位为0,右移后,用0补空位。如果最高位为1,右移后,用1补空位。
b.对于>>>,无论最高位是0还是1,右移后,都用0补空位。
3、进制操作
1、概述:java中有四种进制形式:二进制,八进制,十进制,十六进制。
整数的表现形式:
二进制: 0和1,逢2进1.如110(表示六)
八进制: 0 - 7,逢8进1;以0开头表示。如015(表示十三)
十进制: 0 - 9,逢10进1。如12(表示十二)
十六进制:0 - 9、A - F,逢16进1;以0x开头表示。如0x3c(表示60)
2、进制特点:
a.二进制:始于电信号。任何计算机底层都是用二进制表示的。
b.八进制:将二进制的三位表示一位,即为八进制,最大值为7(2^3-1)。
c.十六进制:将二进制的四位表示一位,即为十六进制,最大值为15(2^4-1)。
d.进制数越大,位数越短。
3、进制间转化:
1)十进制转二进制:取2的余数运算
例:求6的二进制:6/2商3---余0,3/2商1---余1,1/2---余1;最终余1或除尽余0,则将每次除得的余数倒叙排列为110,即十进制的6转为二进制是110.
2)二进制转十进制:取2的幂运算
例:求110的十进制:02^0 +12^1 +1*2^2 = 6,其中012...代表各位数。
3)二进制转八进制:从右向左取二进制三位为一位,不足补0,算出每三位的十进制值(不会超过7)
例:求10011011的八进制:八位补一位为010,011,011;计算010 = 2, 011 = 3, 011 =3;则八进制为233
4)二进制转十六进制:从右向左取二进制四位为一位,不足补0,算出每四位的十进制值(不会超过15,过了9,记为A/B/C/D/E/F)
例:求10011011的十六进制:补位为0000,0000,1001,1011,计算0000 = 0, 0000 = 0,1001 = 9, 1011 = B(11),则十六进制为9B
5)八进制、十六进制转二进制:先转为十进制,再转为二进制。
6)二进制的负数形式:取反后再求其补码
例:求-6的二进制:
0000-0000 0000-0000 0000-0000 0000-0110
^ 1111-1111 1111-1111 1111-1111 1111-1111
--------------------------------------------------------------------
1111-1111 1111-1111 1111-1111 1111-1001
+ 0000-0000 0000-0000 0000-0000 0000-0001
--------------------------------------------------------------------
1111-1111 1111-1111 1111-1111 1111-1010
则-6的二进制为:1111-1111 1111-1111 1111-1111 1111-1010
。
说明:二进制的负数形式的最高位皆为1.
/**
需求|:定义一个方法,使其可将十进制转换为二进制、八进制及十六进制
思路|:查表法|:
1定义一个表,存放十六进制的所有元素,此表也就包含了二进制和八进制的元素
2通过十进制&15(或7,或1)的运算,得到进制最后一位数,倒序存入数组
3然后移位(>>>4或3或1),得到一个新数
4重复此过程,知道数值为零,结束
5将数组打印
*/
import java.util.*;
class Trans
{
public static int scan()
{
Scanner in = new Scanner(System.in);
System.out.print("请输入十进制数字:");
int num = in.nextInt();
return num;
}
public static void trans(int num,int base,int offset)
{
if(num ==0)
{
System.out.println("\n转换后的数为:" + 0);
return ;
}
StringBuffer sa = new StringBuffer();
char[] ch = { '0','1','2','3',
'4','5','6','7',
'8','9','A','B',
'C','D','E','F'};
char[] arr = new char[32];
int pos = arr.length;
while(num!=0)
{
int temp = num & base;
arr[--pos] = ch[temp];
num >>>=offset;
}
for(int i=pos;i<arr.length;i++)
{
sa.append(arr[i]);
}
System.out.println("后的数为:" + sa);
}
//转换为二进制
public static void toBin(int num)
{
System.out.print("转换成二进制");
trans(num,1,1);
}
//转换为八进制
public static void toBa(int num)
{
System.out.print("转换成八进制");
trans(num,7,3);
}
//转换为十六进制
public static void toHex(int num)
{
System.out.print("转换成十六进制");
trans(num,15,4);
}
public static void main(String [] args)
{
int x = 0;
x = scan();
toBin(x);
toBa(x);
toHex(x);
}
}
4、三元运算符:
格式:布尔型表达式 ? 表达式1 : 表达式2
说明:当布尔型表达式的值为true时,则计算表达式1;否则计算表达式2。
如:
返回两个数中较小的值----> x < y ? x : y。
注意:
a.这个是有返回值的,需要由变量接收这个返回值,如:int a = x < y ? x : y;
b.表达式1和表达式2必须都返回相同类型,或是相同类型的数据。
5、运算符优先级:
运算符间有不同的优先级。就是谁先运算的问题。具体如下:从左向右运算的:
运算级别由高到低
1级—— 方法调用:[ ] . ()
2级—— 一元运算符:! 、~ 、++、-- 、+、-;强制类型转换:( );创建:new
3级—— 二元运算符:*和 / 优于 + 和 -
4级—— 位运算:<<、>> 、>>>
5级—— 比较运算符:< 、> 、<= 、>= 、instanceof 优于 ==、!=、
6级—— 逻辑运算符:&、|、^、!、&&、||
7级—— 三元运算符:? :
8级—— 算数运算符等: =、+=、-=、*=、/=、%=、&=、|=、 ^=、 <<=、>>= 、>>>=
上面除了第2、7和8级的是从右向左运算,其他的都是从左向右进行的运算。
6、转义字符:
1、概述:通过 \ 来转变后面字母或符号的含义。如:\n表示换行。
2、常用转义字符:
\b:退格 \n:换行
\t:制表符,相当于tab键 \r:回车
\\:表示反斜杠 ':表示单引号 ":表示双引号
四、final关键字
final:最终。是java中的修饰符
1、final关键字的特点:
1、可修饰类、变量(成员变量、静态变量、局部变量)、函数
2、被final修饰的类不可被继承,为避免被继承,子类需要复写父类中的方法
3、被final修饰的方法不可被复写
4、被final修饰的变量是常量时,只能赋值一次。final既可修饰成员变量,又可修饰局部变量
描述事物时,一些数据为固定的,为增强阅读性,都给这些值起名,而此值不被改变
如:数学函数中的圆周率PI是一个固定值,在java中北定义为final的,是为了让程序更加严谨
public static final double PI = 3.141592654
5、内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量
2、final关键字的体现
1、final方法:
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
也就是说,被final修饰后,是不能有“子方法”的,就是不能在子类中重写父类中的这个方法。
class Fu
{
final void Fun()
{
System.out.println("fu-final");
}
}
class Zi extends Fu
{
void Fun()
{
System.out.println("zi-final");
}
}
class FinalDemo
{
public static void main(String [] args)
{
Zi z = new Zi();
z.Fun();
}
}
当编译运行的时候会出错:
2、final类:
final类是最终类,是不能被扩展的类,即没有子类。因此当类不允许被继承,不允许被改变其中被实现的细节,那么就可以将父类定义成final的。
注意:抽象类不能用final来修饰,即一个类不能既是最终类又是抽象类。