岁寒,然后知松柏之后凋也。 ——《论语•子罕》
Java知识摘要
1 开发环境Java SDK 下载和安装
Java SE Development Kit 8 Downloads
2 环境变量的配置(path和classpath)
JAVA_HOME C:\Program Files\Java\jdk1.8.0_91
CLASSPATH .;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar
Path %JAVA_HOME%\bin
3 编程基础 标识符命名规范
Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。
标识符命名规范
- 标识符由字母、数字、下划线“_”、美元符号“$”组成,第一个字符不能是数字。
- 不能把java关键字和保留字作为标识符。
- 标识符没有长度限制。
- 标识符对大小写敏感。
Java语言规定关键字不能作为标识符。目前共有50个Java关键字,其中,”const”和”goto”这两个关键字在Java语言中并没有具体含义。Java语言把它们列为关键字,只是因为”const”和”goto”是其他某些计算机语言的关键字。
4 Java数据类型
byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
boolean:只有true和false两个取值。
char:16位,存储Unicode码,用单引号赋值。
常见面试题:
1、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 +=1;有什么错? 答:对于short s1=1;s1=s1+1来说,在s1+1运算时会自动提升表达式的类型为int,那么将int赋予给short类型的变量s1会出现类型转换错误。 对于short s1=1;s1+=1来说 +=是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。
2、char类型变量能不能储存一个中文的汉子,为什么? char类型变量是用来储存Unicode编码的字符的,unicode字符集包含了汉字,所以char类型当然可以存储汉字的,还有一种特殊情况就是某个生僻字没有包含在 unicode编 码字符集中,那么就char类型就不能存储该生僻字。
3、Integer和int的区别
int是java的8种内置的原始数据类型。Java为每个原始类型都提供了一个封装类,Integer就是int的封装类。
int变量的默认值为0,Integer变量的默认值为null,这一点说明Integer可以区分出未赋值和值为0的区别,比如说一名学生没来参加考试,另一名学生参加考
试全答错了, 那么第一名考生的成绩应该是null,第二名考生的成绩应该是0分。关于这一点Integer应用很大的。
Integer类内提供了一些关于整数操作的一些方法,例如上文用到的表示整数的最大值和最小值。4、switch语句能否作用在byte上,能否作用在long上,能否作用在string上?
byte的存储范围小于int,可以向int类型进行隐式转换,所以switch可以作用在byte上
long的存储范围大于int,不能向int进行隐式转换,只能强制转换,所以switch不可以作用在long上
5 运算符
运算符按照其要求的操作数数目来分,可以有单目运算符、双目运算符和三目运算符,它们分别对应于1个、2个、3个操作数。
运算符按其功能来分,有算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符和其他运算符。
算术
单目:+(取正)-(取负) ++(自增) - -(自减)
双目:+ - * / %(取余)
三目:a>b?true:false 说明:当a大于b的时候,为true(也就是冒号之前的值),否则为false;这整个运算符包括一个关系运算符(可以是“>””<”“!=”等等),一个“?”,一个“:”,冒号前后需要有两个表达式或者是值或者是对象。
关系
等于符号:==,不等于符号:!= ,大于符号:>, 小于符号:<,大于等于符号:>= ,小于等于符号:<= 。
位与逻辑
位运算符 与(&)、非(~)、或(|)、异或(^)
&:双目运算符,运算时均把运算数转换为二进制再做比较,规则:当相同的位上均为1时结果为1,否则结 果为0.如:1010&1101,转为二进制:1111110010&10001001101,比较结果为:1000000转为十进制: 64。所以1010&1101=64;
| :当两边操作数的位有一边为1时,结果为1,否则为0。如1100|1010=1110
~:0变1,1变0
^:两边的位不同时,结果为1,否则为0.如1100^1010=0110
逻辑运算符
与(&&)、非(!)、或(||)
赋值
= += -= *= /= %= &= ^= |= <<= >>=
instanceof
该运算符是双目运算符,左面的操作元是一个对象,右面是一个类或接口。当左面的对象是右面的类(或右边类的子孙类)创建的对象、或者是右边接口的实现类(或实现类的子孙类)的对象时,该运算符运算结果是true,否则是false。
运算符综述
Java 的表达式就是用运算符连接起来的符合Java 规则的式子.运算符的优先级决定了表达式中运算执行的先后顺序.例如,x < y&&!z相当于(x < y)&&(!z),没有必要去记忆运算符号的优先级别,在编写程序时可尽量的使用括号来实现你想要的运算次序,以免产生难以阅读或含糊不清的计算顺序.运算符的结合性决定了并列相同级别的运算符的先后顺序,例如,加减的结合性是从左到右,8-5+3 相当于(8-5)+3.逻辑否运算符 的结合性是右到左, x 相当于!(!x).表3.4是Java所有运算符的优先级和结合性。
位移
<< 带符号左移 >>带符号右移 >>> 无号右移
运算符优先级
按优先级从高到低排列如下:[ ] ( ) ++ – ! ~ instanceof * / % + - << >> >>> <> < = > \ == != &^& & || ? := op= 。
类型转换
强制和转换
Java语言和解释器限制使用强制和转换,以防止出错导致系统崩溃。整数和浮点数运算符间可以来回强制转换,但整数不能强制转换成数组或对象。对象不能被强制为基本类型。
Java中整数运算符在整数运算时,如果操作数是long类型,则运算结果是long类型,否则为int类型,绝不会是byte,short或char型。这样,如果变量i被声明为short或byte,i+1的结果会是int。如果结果超过该类型的取值范围,则按该类型的最大值取模。
java运算符
&是位
&&是逻辑
当&两边是整数时执行的是位运算,而两边是boolean值时执行的是逻辑运算,
如:
3&6 就是执行的位运算,结果是一个整数:2
true&false 执行的就是逻辑运算,结果是一个boolean值:false
&的逻辑运算和&&逻辑运算是存在一定不同的
&逻辑运算时两边都会计算的,而&&则在左边为假时则直接返的是false不再计算右边
举个例子:
1:
int[] a={1,2,3};
if(a[0]==2&a[2]==4){
System.out.println("true")
}
2:
int[] a={1,2,3};
if(a[0]==2&&a[3]==4){
System.out.println("true")
}
这两个例子中,第一个会抛出异常,而第二个则什么不会输出也不会抛异常
这是因为第一个例子中if语句中用的是&,所以两边的都会计算,当计算a[3]==4时抛出数组下标越界异常
第二个例子则在计算第一个式子a[0]==2发现结果为假则不再计算右边,直接返回false,所以该例子不会输出任何东西 。
3:
java中用的最多的一个三目运算符:A==3?b:c;
如果A=3成立的话结果是b,如果不成立的话结果是c;
运算符演示
int f = -14%4; //f=-2
取模运算符(%),其实就是取除法后的余数,例子中的int f = -14%4,就是-14对4取余数,结果为-2。与C、 C++不同,对取模运算符%来说,其操作数可以为浮点数, 如 37.2%10=7.2
6 分支语句(if,switch)
for (int i = 1; i<=10 ;i++) {
if ( i == 1) {
System.out.println("A");
}
else if ( i == 2) {
System.out.println("B");
}
else if ( i == 3) {
System.out.println("C");
}
else {
System.out.println(i);
}
}
switch (day)
{
case 0:
x="Today it's Sunday";
break;
case 1:
x="Today it's Monday";
break;
case 2:
x="Today it's Tuesday";
break;
default:
System.out.println("并没有匹配的");
break;
}
7 循环语句(for,while)
public class Testjiujiuchengfabiao {
public static void main(String[] args) {
//外层循环控制行数,9行。
//内存循环控制列数、数量。
for(int i=1;i<=9;i++) {
for(int j=1;j<=i;j++) {
System.out.print(i+"*"+j +"=" +(i*j) +"\t");
}
//换行显示
System.out.println();
}
}
}
public class control5{
public static void main(String[] args){
int a=1,result=0;
do{
result+=a++;
}while(a<=100);
System.out.println(result);
}
}
8 函数的定义方法
函数就是定义在类中的具有特定功能的一段独立小程序,函数也称为方法
修饰符 返回值类型函数名(参数类型 形式参数1,参数类型 形式参数2,。。)
{ 执行语句;
return 返回值;
}
返回值类型:函数运行后的结果的数据类型
参数类型:是形式参数的数据类型
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数
实际参数:传递给形式参数的具体数值
return:用于结束函数
返回值:该值会返回给调用者
public class FunctionDemo {
public static void getResult(int num) {
System.out.println(num * 3 + 5);
}
public static void main(String[] args) {
getResult(5);
}
}
9 面向对象基础 面向对象与面向过程语言之间的区别
面向对象与面向过程程序设计有如下不同:
(1)面向过程程序设计方法采用函数(或过程)来描述对数据的操作,但又将函数与其操作的数据分离开来;面向对象程序设计方法将数据和对数据的操作封装在一起,作为一个整体来处理。
(2)面向过程程序设计方法以功能为中心来设计功能模块,难于维护;而面向对象程序设计方法以数据为中心来描述系统,数据相对于功能而言具有较强的稳定性,因此更易于维护。
10 面向对象基本思想(封装)
面向对象主要是把事物给对象化,它的思想体现在:
包含了面向过程的特征,是一种更高级的解决问题的思路——从现实世界中的客观对象出发,尽量运用人类的自然思维方式(如抽象和分类)来构造软件系统
摒弃了数据和功能独立的特点,而是定义为一组正在交互的对象。对象可以完成一些事情(即功能,具体实现表现为类方法),也知道一些事情(即数据,具体实现表现为属性)
用对象的属性表示事物的静态特征,用对象的方法来表示事物的动态特征
运用人类的思维对事物进行分类
类具有封闭性,即把类内部的属性和服务隐藏起来,只有公共的服务对外是可见的
复杂的对象可以用简单的对象作为其构成部分(聚合的思想)
对事物进行分层,采用继承的思想对事物一般化和特殊化
对象之间通过消息进行通信,来实现对象之间的动态联系(消息机制)
从上面的思想可以看出面向对象的三大基本特征:
封装:把客观事物封装成抽象的类。类包含数据和方法,封装即只让可信的类或者对象操作,对不可信的类进行信息隐藏。通过接口,类隐藏其中的属性和方法的具体实现。
继承:按层分类的概念。继承实现了子类和父类:子类可以使用父类的所有功能,并且对这些功能进行扩展。继承的过程,就是从一般到特殊的过程。
多态:同种事物,多种状态,即同一个接口名称,但是体现为不同的功能。多态有两种方式:覆盖和重载。覆盖是指子类重新定义父类的方法,而重载是指同一个中允许存在多个同名方法,而这些方法的参数不同(或者是参数个数不同,或者是参数类型不同,或者两种都不同)。
抽象
抽象就是把事物的信息细节进行提炼、抽象,找到事物的本质和重要属性,以求简化、概括所观察到的现实世界,并为人们所用。抽象包括两个方面,一是过程抽象,二是数据抽象。过程抽象是指任何一个明确定义功能的操作都可被使用者看作单个的实体看待,尽管这个操作实际上可能由一系列更低级的操作来完成。数据抽象定义了数据类型和施加于该类型对象上的操作,并限定了对象的值只能通过使用这些操作修改和观察。抽象是软件开发的基础。
封装
封装(Encapsulation)是面向对象方法的重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。
public class Man {
//对属性的封装,一个人的姓名,年龄,妻子都是这个对象(人)的私有属性
private String name;
private int age;
private Woman wife;
//对该人对外界提供方法的封装,可以设定妻子,姓名,年龄也可以获得男人的姓名和年龄
// 方法封装
public void setWife(Woman wife) {
this.wife = wife;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Woman {
// 属性封装
private String name;
private int age;
private Man husband;
// 方法封装
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Man getHusband() {
return husband;
}
public void setHusband(Man husband) {
this.husband = husband;
}
}
/**
* 仔细看就会发现,Man类没有提供getWife的方法,这是因为男人不想让自己的妻子被外界访问,
*
* 接下来呢,就是封装可以把一个对象的属性私有,而提供一些可以被外界访问的属性的方法,
*
* 比如说,name属性,Man和Woman类都有相应的get和set方法,外界都可以通过这些方法访问和修改
*
* 同时对一些对象不想让外界访问的属性,就不提供其方法,比如说Man的wife属性,就没有get方法
*
* 外界是不能得到Man类的wife属性的
*
*/
上面那例子可能没有突出封装的好处,下面来个超简单的表达下:
public class Show {
public static void show(String str) {
System.out.println(str);
}
}
上面就是对 System.out.println();的封装。
调用的时候 :
public class Use {
public static void main(String[] args) {
Show.show("封装");
}
}
这样用的时候就不用使:System.out.println("封装");
把System.out.println封装起来
封装的作用
对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。
对象的数据封装特性还可以把对象的私有数据和公共数据分离开,保护了私有数据,减少了可能的模块间干扰,达到降低程序复杂性、提高可控性的目的。
11 类的定义方法
[修饰符] class 类名
{
零到多个构造器定义
零到多个成员变量
零到多个方法
}
//设计一个空调
public class Kongtiao {
//空调属性
String name;
String pinpai;
String pishu;
int tempeture;
//定义制冷行为
void cool() {
tempeture--;
}
//定义加热行为
void hot() {
tempeture+=7;
}
//主函数
public static void main(String[] args){
Kongtiao kt = new Kongtiao();
kt.name = "美的";
kt.pishu = "2匹";
kt.tempeture = 20;
kt.pinpai = "志高";
/**
kt.cool();
System.out.println("空调的温度是"+kt.tempeture);
*/
kt.hot();
System.out.println("空调的温度是"+kt.tempeture);
}
}
12 对象和类的关系
类是客观存在的,抽象的,概念的东西。
对象是实际存在的该类事物的个体,称为实例。例如:车是一个类,汽车,自行车就是他的对象。
类与对象的关系:
1.具有相同或相似性质的一组对象的抽象就是类,类是对一类事物的描述,是抽象的,概念上的定义。
2. 对象的抽象化是类,类的具体化就是对象,也可以说类的实例是对象。
3.类概述每个对象的行为特征
13 对象的创建方法
public class Person {
public String name;
public int age;
public void say(String content) {
System.out.println(content);
}
}
Person p =new Person();
p.name = "胖子";
System.out.println(p.name);
p.say("你说胖子是胖子");
14 通过对象使用成员变量和成员函数的方法
class Student{
private String name;
private int age;
public void setName(String name) {
this.name=name;
}
public void setAge(int age) {
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void say() {
System.out.println("我是"+this.name+",我"+this.age+"岁了");
}
}
public class StudentTest{
public static void main(String arg[]){
Student s = new Student();
s.setAge(10);
s.setName("胖子");
s.say();
}
}
15 构造函数的作用
构造函数是一种特殊的函数。其主要功能是用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。构造函数与类名相同,可重载多个不同的构造函数。JAVA语言中普遍称之为构造方法。
构造方法是一种特殊的方法,具有以下特点。
(1)构造方法的方法名必须与类名相同。 (2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。
(3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。
(4)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
(5)构造方法可以重载,以参数的个数,类型,顺序。
java构造函数的调用问题(不能继承)
(1)子类只调用父类的默认(缺省)构造函数,即无形参构造函数。如果父类没有默认构造函数,那子类不能从父类调用默认构造函数。
(2)子类从父类处调用父类默认构造函数,不能成为子类的默认构造函数。
(3)在创建对象时,先调用父类默认构造函数对对象进行初始化,然后调用子类自身自己定义的构造函数。
(4)如果子类想调用父类的非默认构造函数,则必须使用super来实现。
(5)子类必须调用父类的构造函数。可以通过系统自动调用父类的默认构造函数,如果父类没有默认构造函数时,子类构造函数必须通过super调用父类的构造函数。
class Student{
private String name;
private int age;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public Student(int age) {
this.age = age;
}
public void say() {
System.out.println("我是"+this.name+",我"+this.age+"岁了");
}
public void say1() {
System.out.println("我"+this.age+"岁了");
}
}
public class StudentTest {
public static void main(String arg[]) {
Student s = new Student(134,"peng");
Student s1 = new Student(34);
s.say();
s1.say1();
}
}
16 函数的重载
1针对同一个类中的一个函数来说的;
2,这组函数中,函数名称相同(一般情况下建议功能相似的函数才做函数重载);
3,形式参数不相同,包括参数的个数不同、参数的类型不同或参数个数和类型都不相同;
4,与函数的返回值类型没有关系
class ChongZai{
public void a(int a);
public void a(Strting a);
public void a(int a,int b);
}
重载Overloading是一个类中多态性的一种表现