写源文件,源文件的扩展名是.java
对源文件进行编译
不带包名的编译
rem
目录:>javac HelloWorld.java
带包名的编译
rem
目录:>javac -d . HelloWorld.java //.就是当前文件夹
对编译生成的.class文件做执行
不带包名的执行
目录:>java HelloWorld
带包名的执行
目录:>java cn.edu.tit.core.java.test.HelloWorld
类名每个单词首字母都大写
方法名首字母小写,后面首字母大写,构造方法首字母大写和类名一样
变量名、属性名首字母小写,后面首字母大写,驼峰Camel命名法
项目、包名名全小写
接口名以 I 开头
运算符" = “左右加空格” "
方法、属性前都要加注释(方法名、形参[param]、返回值[return]都要注释) ** /+Enter 文档注释
public class Student {
/**学生姓名*/
private String name;
/**
* 学生根据课程名称选课
* @param courseName 学生选择的课程
* @return 如果选课成功返回true,否则饭后false
*/
public boolean selectCourse(String courseName) {// course课程
System.out.println("我选择了课程:" + courseName);
return true;
}
}
API文档:(JavaDoc文档)项目的说明文档:Project>Generate Javadoc
-encoding utf-8 -charset utf-8
a*1.0
将整数int a 变为小数float a3.0/0
正确 3/0
错误//用sc对象接收键盘数据
Scanner sc = new Scanner(System.in);
System.out.println("请您输入出生年份");
//接收用户在键盘上输入的整数
int birthyear = sc.nextInt();//控制回车输入
sc.next()//不吸取字符前/后的空格/Tab键,直到遇到空格/Tab键/回车截止吸取
sc.nextLine()//吸取字符前后的空格/Tab键,回车键截止
Math.random() //获取(0,1]之间的随机小数
Math.random()*50 //获取(0,50]之间的随机小数
(int)(Math.random()*50) //强制转换为整数
//四舍五入
java.text.DecimalFormat df=new java.text.DecimalFormat("0.00");//保留2位
double d=3.148;
System.out.println(df.format(d)); //输出3.15
//全部舍去 得导入import java.math.BigDecimal包
BigDecimal bd = new BigDecimal(3.148);
bd = bd.setScale(2,BigDecimal.ROUND_FLOOR); //保留2位
System.out.println(bd); //输出3.14
//小数点后全部舍去,并保留小数点一位0
double d = 13.4324;
d=((int)(d*100))/100;//输出13.0 因为d还是double型
System.exit(0);
\
转义字符,让后面字符失去特殊的含义\t
制表符,tab,补全当前字符串长度到8的整数倍,最少1个最多8个空格\n
换下一行,不换列 next\r
回车,回到当前行的行首,不换行/**+Enter
文档注释//
单行注释/*
多行注释main
生成主方法{ }
游离语句块@Override
注解package cn.edu.tit.core.java.test01;
//如果在一个java文件里有多类,保存文件的时候,要求:文件名和被public修饰的类名一致
//所以在一个java文件里最多有一个public类
public class Animal{
//public类名Animal 应该与文件Animal.java一致
}
class Dog{
}
class Cat{
}//生成了三个.class文件
一直点下一步,点Finish,生成jar包
.jar本质是java语言的压缩格式
在项目目录里导入jar包
JDK、JRE、JVM关系是什么?
答:JDK(Java Development Kit)-Java开发工具
JRE(Java Runtime Environment)-Java运行环境
JVM(Java Virtual Machine)-Java虚拟机
JDK开发工具包括JRE运行环境(JVM虚拟机+Java系统类库)和Java工具
Java程序的执行过程?
答:编写.java源程序,用javac编译(compile)产生.class文件,用java命令执行.class文件,显示相应的效果
答:**字节码(*bytecode*)**文件
.class文件中是什么内容?
答:JVM能够识别的字节码,内容是16进制
.class文件是平台相关or无关?
答:平台无关/跨平台
#Java语言唯一跨平台
.class文件可以看到吗?
答:可以看到
#UE(UltraEdit)文本编辑器 16位字节码 第一行是CA FE BA BE(咖啡宝贝)
JVM是平台相关or无关?
答:平台相关,不同OS(operating system)有不同JVM
JVM的作用是什么?
答:将字节码文件翻译成特定平台的机器指令
#机器语言(机器码/原生码)->汇编语言->高级语言
Java平台的划分?
Java语言有什么特点?
Java语言是编译型or解释型?
答:二者结合
C/C++/Java的区别?
答:C:硬件编程、算法(与数学有关)、操作系统级编程(与硬件有关)
C++:面向对象,但不是纯正的OOP,在C基础上加入了OOP的内容
算法、图形图像软件、嵌入式QT、通讯软件、工业控制软件等
Java:纯OOP,纯面向对象,开发B/S结构的大型Web应用、教务系统、12306、Android APP;Java大数据开发 #平台无关
C#:和Java类似,是微软的技术,开发的软件只能在Windows执行,VR、U3D,极少人
Go:
Python:
HelloWorld面试题:
public去掉:可以编译,不能执行
static去掉:可以编译,不能执行
void去掉:不能编译
String去掉:可以编译,不能执行
String[] args去掉:可以编译,不能执行
args改变:可以执行
[]改变:可以执行
public static->static public:可以执行
static void->void static:不能编译
…->void main(){}:可以编译,不能执行
#保存后出现红波浪线则不可以编译
javac和java面试题
一种编程方式,也是一种编程思想(就是思考问题的方式)
P.S. 编程方式有哪些?
P.S.软件开发的流程是什么?
写类——创建对象——对象调用方法(属性)
Q:先设计,根据设计写代码,先技术谁?A:类
写类
类:类型的简称 同一类型抽象的概念
类=属性+方法
设计类:ULM设计工具 统一建模语言(Unified Modeling Language) 用来设计软件的语言,不是编程,是图形符号
方法(操作/函数):可见性(visibility)[pubilic/private]、返回类型、方法名、形式参数、方法体
可见性 返回类型 方法名(参数类型 形式参数){方法体}
方法不能嵌套
构造方法:名字和类名相同,没有返回类型
一个类可定义多个构造方法
构造方法的作用?
public class Teacher {
private String teacherName;//属性
//给对象的属性赋值:没有返回值:*构造方法↓ 方法名和类名相同
public Teacher(String name) {
[前面属性定义类型]teacherName = name;
}
//不是构造方法,有返回类型void,是一般方法↓
public void Teacher{}
//不是构造方法,名字大小写不一样
public teacher{}
//无参构造方法
public Teacher{}
**在JAVA中如果不写构造方法的话,会默认加上一个无参数的构造方法**,但是如果已经有了一个有参数的构造方法,那么无参数的构造方法就不会默认被加上.
如果Hello类中已经有了一个有参数的构造方法,这时再使用 Hello hello = new Hello();来创建对象的时候就会出错,这就是为什么书上要强调写了有参数的构造方法就**最好加一个无参数的构造方法**.
**构造方法的重载**:方法名相同,但参数不同的多个方法,调用时会自动根据不同的参数选择相应的方法。
```java
Hello hello = new Hello()//调用无参构造方法
Hello hello = new Hello("h")//调用有参构造方法
属性:可见性 类型 属性名;
可以自定义初值
属性都有默认初值,对象默认为null,数字默认为0
public class Teacher {//在类开头建属性
private int age = 30;//30
private int telnumber;//0
private String name;//null
}
显式赋值和默认赋值
String name ="tit"; //显式赋值
int age; //默认赋值
属性赋值过程如何? 父类->子类
默认赋值
显式赋值
构造方法赋值
String name = "tit";
new Student ("nuc");
//name值变化过程如何?
//null-->tit-->nuc
建对象(放在堆区)
对象:具体,世间万物皆对象
拥有所属类的全部属性
类 对象名 = new 构造方法()
//建对象
建变量:类型 变量名
每个变量都有确定的类型
对象调属性
对象.属性
//用对象的属性对象调方法
对象.方法
(实际参数
)代码:
public class Student {//写类
/**学生姓名*/
private String name;//写属性
public void bite(String name) {
System.out.println(name + "被咬了!");//写方法
}
}
public static void main (String[] args) {
Student lizeya = new Student();//创建对象,使用new新建对象
lizeya.bite("图灵");//对象调用方法,完成功能
}
>>>图灵被咬了!
Q&A
什么是OOP?
A:面向对象程序设计
面向:按照,强调,针对
类和对象有什么区别?
A:类是抽象的,对象是具体的,类是对具有共同特性的概括
面向对象和面向过程的区别?
面向对象(OOP)的特征?
四种整型数
byte字节型:
长度1个字节,8位,范围-128~127
short短整型:
长度2个字节,16位,范围-32768~32767
int整型(整数默认):一般地整型变量默认为 int 类型
长度4个字节,32位,范围-2,147,483,648~2,147,483,647
long长整型:
长度8字节,64位,范围-2(n-1)~2(n-1)-1
2,147,483,648L
L/l必须有,不建议用l
2,147,483,647
当小于等于int最大值,可以不加L/l
其他
char字符型:(汉字2字节)
【字符用单引号' '
,字符数不用】
长度2个字节,16位,范围:0~65535。本质是数字
一般输出为字符,97
和'\u0097'
都输出a
转义字符
Java用Unicode编码
float浮点型: 十进制浮点数->二进制浮点数 可能产生精度损失
1 - 0.9 = 0.09999999999999998
长度4个字节,32位
1.8F
F/f必须有 1.8
错!
.8F = 0.8 8.F = 8.0
double双精度浮点型(小数默认):
长度8个字节,64位
boolean布尔型:
长度无精确定义,取值是true/false 不能是1/0
String不是内置类型,只是API应用程序接口(Application Program Interface)中的一个类
Q:Java语言各种数据类型长度如何?数据类型的长度会不会随平台变化?
A:不会!
BigDecimal
来表示金额,或者是通过将金额的单位变小用整数来表示金额。(引用类型以对象形式存在,有属性和方法)
Address addr;
(自己编写的类)String name;
boolean不参与
byte1,short2,char2—> int4 —> long8—> float4 —> double8
低级给高级,自动转换
高低给低级,强制转换
int num1 = 90;
double num2 = 100;
num1 = (int) num2; //强制转换,失去位数
属性都有默认值,对象类型默认值为null,整数为0,浮点数为0.0,字符型为0,布尔型为false
什么是标识符?命名规则是什么?
A:标识符就是名字,以 _、$、文字开头,后面可以是数字、_、文字、数字(长度不限)
什么是关键字?特点?
A:保留字,有特殊含义,全大写,标识符不能用
null/true/false不是关键字,也不能起名字
局部变量和成员变量的区别?
A:属性就是成员变量,有默认值
方法内定义的变量、形参是局部变量,无默认值,必须明确赋值
当局部变量和成员变量名字相同时,局部变量会覆盖成员变量
如何区分——看定义的位置
内存逻辑划分?各部分作用?
栈:先进后出,压着
存放局部变量:由OS管理:用于频繁的数据交互
堆:存放new出来的对象【大于栈】
全局数据区:存放全局变量
代码段:存放程序代码
java中的垃圾回收机制(GC机制[Garbage Collection])?
A:垃圾:无用对象
Java语音采取自动垃圾回收机制
有一个垃圾回收的线程,在扫描内存中的无用对象,无指向的对象,自动回收
目的:减轻程序员的负担,减少了内存泄漏
能不能通过编程手段强迫JVM进行垃圾回收?
A:不能。 System.gc()
也不行,仅仅建议JVM进行垃圾回收
finalize()
回收前最后一个运行一次的方法
Java回收中是否有可能存在内存泄漏?
A:有可能存在
包名字命名规则
目的:多人开发,不同人不同包,避免类名相同引发的冲突
全小写,不建议使用数字
域名倒写+系统名+模块名字+层次名
cn.edu.tyust.项目代号.模块代号
cn.edu.tyust.hr.emp;
package cn.edu.tit.jobtrace.student.vo//层次名
package cn.edu.tit.jobtrace.student.service
package cn.edu.tit.jobtrace.student.dao
导入包
import java.util.Scanner; //导入包内一个类
import java.util.*; //导入包内所有类
常用包
java.lang
核心包,直接可用,自动导入
.lang.reflect 反射相关(不支持嵌套导入)
.io 输入输出包,文件读写
.util 工具包
.Math 数学包
.text 文本处理
.sql 数据库
基础包:java开头
扩展包:javax开头
第三方包:org/com开头
自定义包:自己编写的
算数运算符
关系运算符
== != > < >= <=
逻辑运算符
位运算符
八位二进制,第一位为符号位,0是正,1是负
& | ^ ~ << >> >>>
A = 0011 1100 //60
B = 0000 1101 //13
-----------------
A & B = 0000 1100
//&:与(乘),对应位都为1,则结果为1,否则为0
A | B = 0011 1101
//|:或(加),对应为都为0,则结果为0,否则为1
A ^ B = 0011 0001
//^:异或,对应位相同,则结果为0,否则为1
~A= 1100 0011
//~:取反
A << 2->240,即 0011 1100->1111 0000
//按位左移运算符,低位补0
A >> 3->7,即 0011 1100->0000 0111
//按位右移运算符,高位补符号位
A >>> 2->15,即 0011 1100->0000 1111
//无符号右移,按位右移补零操作符,高位补0
赋值运算符
+= -= *= /= %= &= |= ^= >>= <<=
i += 1
运算速度快于 i = i +1
没有开辟新存储单元
short a = 1;
a = a + 1
错误!! 其中1默认是int型,高级->低级 错误!
a += 1
正确!! a = (short)(a + 1)
正确!!!
↑ byte,char,short类型在运算的时候自动变成int,或者说是JVM把它们以int来考虑。只要右侧的值不超范围就对。
补充:
/
整除时舍去全部小数)if , if else , for , while , do while , switch , break , continue
条件语句
Q:switch()中的变量可以是什么类型?
A:String,byte,short,int,枚举
(长整型long,布尔型boolean,浮点数不可以!)
--------------------swtich case语句-----------------------
switch(expression变量){
//判断一个变量与一系列值中某个值相等,每个值称为一个分支
case value://跟冒号:,value是常量
//语句
break;//可选,break跳出整个switch语句
case value:
//语句
break;//可选
case 1:
case 2://1和2可用同一个break,不能用||或
break;
//你可以有任意数量的case语句
default://默认可选,Java关键字,没有顺序
//语句
}
-----------------------if else语句------------------------
if(布尔表达式){
//如果布尔表达式的值为true
}
else{//可选
//如果布尔表达式的值为false
}//可以嵌套if语句
-----------------if...else if...else语句------------------
if(布尔表达式 1){
//如果布尔表达式 1的值为true执行代码
}else if(布尔表达式 2){
//如果布尔表达式 2的值为true执行代码
}else if(布尔表达式 3){
//如果布尔表达式 3的值为true执行代码
}else {
//如果以上布尔表达式都不为true执行代码
} //if 语句至多有 1 个 else 语句
------------------------while语句-------------------------
while( 布尔表达式 ) {//为true被执行,false终止
//循环内容
}
--------------------do...while语句------------------------
do {
//代码语句
}while(布尔表达式);//为true被执行,false终止
------------------------for语句---------------------------
for (初始化;boolean表达式;循环更新){//为true被执行,false终止
循环语句 //↑表达式可为空
//循环更新语句在循环语句后执行
}
----------------------for each语句------------------------
for(声明语句int x : 表达式intArray)
{
System.out.print( x );//代码句子
}//输出12345678
---------------------死循环-----------------------------
for(;;){}
while(ture){}
while(1){}
总结:数组是一种线性(类型单一)数据结构,不能在一个数组里存放不同类型的数据。数组的长度在new的时候指定。不能越界取值或赋值。有默认值。
dataType类型[] arrayRefVar数组名; // 首选的方法,[]放中间
int [] intArray;
或
dataType arrayRefVar[]; //效果相同,但不是首选方法,C/c++是这样
使用new
,在new的时候在右边[ ]
指定长度
int [] score = new int[4];
//长度4,即0~3四个元素,不可省略
静态初始化
声明时赋值
int [] intArray = {34,45,21,90};
//错误!!! intArray = {34,45,21,90}
//错误!!! int [4] intArray = {34,45,21,90}
元素默认初值,随类型默认值,int 为 0
new创建时赋值
int [] sa = new int[] {10,20,30};//逗号隔开
//不能写长度
直接赋值
int [] score = new int[4];
score [0] = 10;
score [1] = 20;
//错误!! score [4] = 50; 第5个元素>数组长度4
动态初始化
int [] roommateNum = new int[8];
for (int i = 0; i < roommateNum.length; i++) { roommateNum [i] = i+1 ; }//java不允许跨界取值
ystem.out.println(roommateNum[7]);//输出8
面试题
length和length()什么区别?
A:length是数组的属性,代表数组长度;length()是String类的方法。
数组是不是引用类型?
A:是。引用类型有三种:类,接口,数组。
引用类型以对象形式存在。所以放在堆区。
冒号排序
public void sort (int [] beforeArray) {
//形参beforeArray已被排序
int temp = 0;
for (int i = 0; i < beforeArray.length-1; i++) {
//单次冒泡,比较次数i越来越少
for (int j = 0; j < beforeArray.length-i-1;j++) {
//如果左边大于右边,位置互换
if (beforeArray[j] > beforeArray[j+1]) {
temp = beforeArray[j];
beforeArray [j] = beforeArray[j+1];
beforeArray [j+1] = temp;
}
}
}
}
public static void main(String[] args) {
BubbleSort bubbleSort = new BubbleSort();
int [] score = {100,90,80,70,60,50,40,30,20,10,0};
//实参score已被排序,不用赋值
bubbleSort.sort(score);
for (int x: score) {
System.out.println(x);
}
}
利用Java API对数组进行排序
import java.util.Arrays;//从小到大排序
Arrays.sort(数组);
private修饰的属性,只有在本类、当前类中使用或可见。
对类的复用(重用)
语法规则:class 子类名 extends 父类名
public class Food (int n){//有参构造方法
int prize;
String color;
}
class Banana extends Food{
super(20);//用super调用父类的有参构造方法
char vitamin;
}
java中支持多重继承吗?
A:不支持。java中使单继承。
一个类只能有一个直接父类
父类没有无参构造方法,还能创建子类对象吗?
A:可以。只不过我们需要改变程序的默认行为,明确指明调用哪个构造方法(因为默认没有无参方法)
使用super()
关键字调用父类的有参构造方法,必须放在构造方法的第一行
子类方法中如何调用父类的一般方法?
A:super.父类方法()
或者直接调用 父类方法()
子类方法中如何使用父类的同名属性?
A:super.父类属性
直接调用的话,因为就近原则,调用子类属性
父类的方法无法满足子类的需要,子类可以对父类的方法进行重写
本质就是改变方法体
构造方法不能重写 因为不能被继承
规则:方法名相同、参数列表相同(不考虑形参的名字)、返回类型相同、访问控制符相同或范围更广。
public class Person(){
String name;
protected void speak(String t,int a){
System.out.println("Person");
}
}
class Student extends Person {
int score;
public void speak(String h,int b){//重写
System.out.println("haha");
}
}
父类中的equals()无法实现正确的比较,我们就可以重写他。
在一个类里有多个同名方法。就构成了方法的重载
规则:方法名字相同,参数列表必须不同,返回类型和修饰符不限
重载发生在一个类的内部,重写发生在有继承关系的两个类之间。
构造方法可以重载
如何在本类的一个构造方法中调用另一个构造方法?
使用this()
这种写法,必须在方法的第一行
this代表当前类,本类对象
protected void speak(String a,int b){}
public void speak(){
this("哈哈",23);//调用第一个构造方法
}
如果一个类里有抽象方法,那么这个类一定是抽象类
abstract
修饰的class类 【可在修饰符前后,一般在public后】abstract
修饰 且 没有方法体【没有{ }】 的方法多态:多种形态,多种状态。一个对象被多种称谓。
ps:非洲无毛狗<狗<动物;
他们之间有继承关系,因此多态发生的话,前提条件是有继承关系或实现关系存在。
子类对象被声明为父类类型。=
左右两边类型不同,左父右子。
子类能调用父类方法,父类不能调用子类方法
HairlessDog dog1 = new HairlessDog();//不是多态
Dog d = new HairlessDog();//是多态,d的类型是Dog
Animal a = new HairlessDog();//是多态
Animal a2 = new Dog();//是多态
-----------------------------------------------------
PersonImpl person1 = new PersonImpl();//不是多态
Iperson person2 = new PersonImpl();//是多态
person2.eat();//接口对象可以调用实现类的接口方法
增强代码的复用性;在这个例子里,增强方法的适应能力,形参可以接收很多对象了。
instanceof
用于判断对象类型,返回值是boolean
instance:实例(对象),创建对象(实例化)
Animal a = new HairlessDog();
System.out.println(a instanceof Animal);//Ture
System.out.println(a instanceof Animal);//Ture
System.out.println(a instanceof Animal);//Ture
与方法重写有关系
在多态情况下,如果子类重写了父类的方法,方法调用以子类为准。
//虚方法调用
IPerson person = new PersonImpl();
person.speak();//以PersonImpl子类为准
person.eat();//以PersonImpl子类为准
接口是java中引用类型之一(类、数组、接口)
作用:解耦。(降低耦合,结合起来) 为了软件容易维护
高内聚,低耦合(在一个模块内部内聚行越高越好,不同模块之间耦合度越低越好,没关系最好)
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量
解耦字面意思就是解除耦合关系,减低耦合度
I
开头命名 public interface IPerson
{ }
,可以是default,static
方法(JDK 1.8 以后,接口里可以有静态方法和方法体了。)public abstract
修饰public static
修饰implements 实现接口的类名为****Impl
结尾
类在实现接口的时候,方法前的public是必须的,因为重写规则要求
//类实现接口的时候,要把接口的抽象方法都要变成具体方法
//如果没有全部具体化接口中的抽象方法,那么这个类就成了抽象类了
public class PersonImpl implements IPerson{
@Override //类在实现接口的时候是对其中抽象方法的重写
public void speak(){
System.out.println("speak");
}//接口中为public void speak(){}
}
Q:接口是特殊的抽象类?
A:不准确
Q:接口能建对象吗?
A:不能,准确类才能
Q:接口如何用?
A:被类实现,类Impl+implements
+接口
实现接口的类名为Impl 结尾
Q:一个类能否实现多个接口?
A:可以,implements class1,calss2,calss3{}
间接实现了多重继承
Q:一个类能否有多个直接父类?
A:不能,单继承。Java里不支持多重继承
Q:接口之间的继承关系如何?
A:接口之间可以继承 extends
接口之间支持多重继承
public interface IThird extends IFirst,ISecond{}
Q:接口与抽象类的区别?
A:接口:
接口是引用类型之一,接口中的方法是抽象的/是default/static的;
属性默认被public,static,final修饰;
接口作用是解耦;
接口不能建对象;
类来实现接口。 接口不是类,没有构造方法
抽象类:
被子类继承,为了类的重用(复用);
抽象类中有构造方法,可以有具体方法;
接口和抽象类是不同的数据类型
Q:抽象类中一定有抽象方法吗?
A:不一定
Q:有抽象方法的类,一定是抽象类吗?
A:一定是。
Q:抽象类能否实现接口?
A:能
Q:抽象类能继承接口吗?
A:不能
Q:接口能继承抽象类吗?
A:不能,不是一种东西
Q:类能否实现多个接口?
A:能
Q:接口能实现接口吗?
A:不能,只能继承
Q:继承父类(较具体)和实现接口优先性?
A:一个类可以先继承extends,再实现接口implements;
不可以先实现接口,后继承
final能够修饰:属性、变量、方法、类
修饰属性、变量:值不能更改,也就是常量
修饰方法:这个方法不能被重写
修饰类:这个类不能被继承
面试题:
被final
修饰的属性,只能显式赋值,或者构造方法赋值,二选一。
final
修饰复合类型(对象),对象的属性可以修改。
A:构造方法能否被final修饰?
Q:不允许
A:final和abstract能否同时修饰一个类?
Q:不能,final不允许继承,abstract需要被继承
public class Doctor {
final int age;//构造方法赋值
public Doctor(int age) {
this.age = age;//this为当前类对象
}
}
----------------------------------------------
public class Doctor {
final int age = 21;//显式赋值
int weight;//不被final修饰,之后可以修改
}
static可以修饰:属性、一般方法、游离块static{ }
、内部类
static{ }
游离块在main之前就要执行。与类加载机制有关。在类加载的时候就执行了,静态static执行只有一次。
static
修饰称呼:
<类>.<属性>
或者<对象>.<属性>
<类>.<方法>
或者<对象>.<属性>
static属性和方法,可以用类名直接调用,可以不创建对象。当然,对象也能调用属性和方法。
new Student().eat();//没有对象名,匿名对象
//<对象>.<方法>
Student.eat(); //类名直接调用
eat(); //相当于当前类调用
static修饰属性:被所有对象和本类对象共享,在内存里只存储一个,全部对象的静态属性值一致。
非静态属性每个对象拥有自己的一个。
public class Student {
static int age;
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.age = 11;
s2.age = 88;
System.out.println(s1.age);//88而不是11
System.out.println(s2.age);//88
Student.age = 100;//类直接调用属性
System.out.println(s1.age);//100
}
}
static修饰方法:
静态方法里不能用非静态属性,只能用静态属性。
静态方法里可以用对象.eat()
调用非静态方法,不能直接eat()
调用。
非静态方法可以用静态属性。
面试题:
Q:static能不能修饰外部类、局部变量和构造方法?
A:不能
Q:static属性存放在内存的哪个区域?
A:全局数据区(全局区)
Q:static变量何时加载?加载几次?加载次序如何?
A:类被载入JVM的时候就加载了,在主方法之前;
加载一次;
按定义的先后次序加载。
Q:static游离语句块何时加载?有何作用?加载次序如何?作用如何?
A:类被载入JVM的时候就加载了,在主方法之前;
加载一次;
按定义的先后次序加载;
作用:在主方法main初始化前,做初始化用。
Q:static方法中能否调用非静态方法?非静态方法能否调用静态方法?
A:static方法可以通过对象调用.speak()
非静态方法,不能直接调用speak()
;
非静态方法可以直接调用静态方法。
Q:主方法main前static可以省略吗?
A:不可省,因为方法调用需要类名.方法
,否则主方法不能被调 用,死锁。static可以直接调用。
Q:static语句块或方法中能否使用super
或this
?
A:不能,super和this属于实例变量(非静态变量)
Q:static方法的虚方法调用有什么特点?
A:虚方法调用对静态方法无效
多态情况下,方法调用以父类为准,因为在类加载前就加载
Q:完整的对象构造次序?
A:父类静态->子类静态->父类的非静态->父类的构造方法->子类的非静态->子类的构造方法(相同则按前后顺序)
public class Student {//stu是属性
Student stu = new Student();//反复执行报错
//static Student stu = new Student();第一执行
//加static输出aaa aaa
public Student() {
System.out.println("aaa");
}
public static void main(String[] args) {
new Student();//匿名对象 第二执行
}
}
public class Student {//父类
public static void eat() {
System.out.println("Eat");
}
public void play() {
System.out.println("Play");
}
}
class HaoStudent extends Student{//继承
public static void eat() {
System.out.println("HaoEat");
}
public void play() {
System.out.println("HaoPlay");
}
public static void main(String[] args) {
Student stu = new HaoStudent();//多态
eat();//输出HaoEat static方法可以直接调用,相当于本类对象调用HaoStudent.eat()
//play();//非静态方法不能直接调用,必须对象.方法()
stu.play();//输出HaoPlay 非静态方法调用虚方法,以子类为准
stu.eat();//输出Eat 静态方法调用虚方法,以父类为准
//Student.play();//非静态方法,类名不能直接调用,需要创建对象
Student.eat();//输出Eat static方法有,可以用类名(匿名对象)直接调用
//HaoStudent.play();//非静态方法不能直接调用,必须对象.方法()
HaoStudent.eat();//输出HaoEat static方法有,可以用类名(匿名对象)直接调用
}
}
OOP方法论(高内聚、低耦合、易复用)
OCP开放封闭原则(开闭原则):
软件实体应该对扩展开放,修改封闭
DIP依赖倒置原则(Spring大量使用)
LSP替换原则
ISP接口隔离原则:(利用接口解耦)
SRP单一职责原则:(类的职责单一)
CARP合成/聚合复用原则:(对象委托优于类继承,Spring大量使用)
LoD迪米特原则/最少知识原则
模式就是套路,就是一种通用方法或手段。
一般在框架里用的很多,比如:Spring框架
《Java与模式》《Head First设计模式》
菜鸟教程 https://www.runoob.com/design-pattern/design-pattern-tutorial.html
创建型模式:
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式:
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式:
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
为什么使用模板方法模式?模板方法模式是什么?
代码实现:
特点:
什么时候用?
例如:Spring中 JDBCTemplate
Q:解决什么问题?
A:一个类只能创建一个对象。
Q:什么时候用?
A:只需要单一对象的时候。比如:帮助->单个窗口
两种实现方式
public class Person{
//一、private static属性,当前类类型,立即初始化(显式赋值)
private static Person person = new Person();
//二、private构造方法私有
private Person(){}
//三、提供public static方法,返回当前类对象
public static Person getPersonInstance(){
return person;
}
}
public class Student {
private static Student student;//默认为空
private Student(){}
public static Student getStudentInstance(){
if(student == null){
student = new Student();
}
return student;
}
}
二者区别:
创建单例对象的时间点不同,饿汉式早,懒汉式晚。
饿汉是属性上直接赋值;懒汉在方法调用的时候创建对象。
Q:请列举几个java设计模式。
A:单例模式(手写)、工厂模式(手写)、适配器模式、装饰模式、模板方法模式、观察者模式、MVC模式。
脱离IDE,建议先画UML类图,再写代码。
//Employee抽象类
public abstract class Employee {
/**
* 模板方法
*/
public void gotoWork() {
comeToCompany();
work();//具体方法无法确定,不同的员工有不同的工作
leaveCompany();
}
public void comeToCompany() {
System.out.println("来到公司打卡……");
}
/**
* 抽象方法,具体不同员工不一样
*/
public abstract void work();//抽象方法
public void leaveCompany() {
System.out.println("下班打卡离开公司……");
}
}
//Hr类
public class Hr extends Employee {
public void work() {
System.out.println("查看简历……通知面试……");
}
}
//Developer类
public class Developer extends Employee {
public void work() {
System.out.println("写代码……改Bug……");
}
}
//Test测试类
public class Test {
public static void main(String[] args) {
Hr hr = new Hr();
hr.gotoWork();
System.out.println("----------------------");
Developer developer = new Developer();
developer.gotoWork();
}
}
//执行Test类,输出
/**
*
来到公司打卡……
查看简历……通知面试……
下班打卡离开公司……
----------------------
来到公司打卡……
写代码……改Bug……
下班打卡离开公司……
*/
Java SE(Java应用)
API(Application Programming Interface)应用编程接口
Spring Boot、Spring Cloud
教务系统:教务管理、学历验证、支付、短信验证码、学生身份户籍信息。
提示:String不是关键字。也不是Java的内置类型。
链式编程风格:name.trim().equalsIgnoreCase(“鸭梨亚”)
int String = 90;//正确
Q:列举几个常用的被final修饰的类
A:String,Math,System,Integer等
String(char[] c)//字符数组->字符串;
String(byte[] bytes,String charsetName);
//处理中文乱码,用到了String构造方法
String newName = new String(name.getBytes("ISO-8859-1"),"UTF-8");
char [] toCharArray()//字符串->字符数组;
boolean endsWith(String str)//返回字符串最后一位;
int length();//获取字符串长度
boolean equals(String str);//区分大小写比较
boolean equalsIgnoreCase(String str);//忽略大小写比较字符串
String trim();//去除字符串首尾的空格
indexOf();//获取首次出现的位置
lastIndexOf();//获取最后出现的位置
substring(2,4);//截取[2,4)
substring(3);//取3到结束
substring(1,1);//得""空字符串
split();//字符串的分割,需要转义,正则表达式
StringTokenizer();//强力分割,字符串分隔解析类型,不需转义
replaceAll("regex", "replacement")//替换
replace(char,newchar)//替换字符
charAt(int index)//返回最后一个字符
//不可变字符串类,指的是字符串的内容不可变
String str = "china";
str.toUpperCase();//str是china,没有改变,因为有返回值
String str2 = str.toUpperCase();//str是CHINA
//可变字符串类,指的是字符串的内容可变
StringBuffer str1 = new StringBuffer("china");//API
//StringBuffer str2 = "tit"错误,不能直接建对象
str1.append(" shanxi taiyuan tit cs").append(" math");
//str1变成了china shanxi taiyuan tit cs math
//"a"+"b"+"c"就是StringBuffer.append()
StringBuilder stringBuilder = new StringBuilder(oldTelNum);//String类型包装成StringBuilder类型
return stringBuilder.toString();//转为String类型
System.currentTimeMillis()
获得系统时间长整型long毫秒ms,System.arraycopy(first, 1, second, 2, 3);
从数值first的位置1开始,替换数值second的位置2,共替换3个System.gc()
建议(不强制)执行垃圾回收器,并不立刻回收Runtime.getRuntime().gc()
更高效System.exit(code状态码)
退出程序PI
和E
属性Math.abs()
取绝对值Math.sin()
正弦,角度范围在 -pi/2 到 pi/2 之间,即-180度 到 180度Math.asin()
返回弧度值,pi是360度Math.ceil()
向上取整数Math.floor()
向下取整数Math.round()
四舍五入【面试题】Math.random()
[0,1)随机小数double【面试题】(int)(Math.random()*1000)
生成[0~1000)的随机整数//生成0~1000的随机整数
import java.util.Random;
Random rd = new Random();
System.out.println(rd.nextInt(1000));
不建议用Date,用Calendar(日历)代替
//用Date获取当前时间
Date date = new Date();
return date.toLocaleString();
>>>返回 2020-5-22 14:03:44
//用Calendar获取当前时间
Calendar calendar = Calendar.getInstance();
//MONTH从0开始记,所以要+1
return ""+calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONDAY)+1)+"-"+ calendar.get(Calendar.DAY_OF_MONTH)+" "+calendar.get(Calendar.HOUR_OF_DAY)+ ":"+calendar.get(Calendar.MINUTE)+":"+calendar.get(Calendar.SECOND);
>>>返回 2020-5-22 14:3:44
可以修饰属性、构造方法、一般方法。
不能修饰局部变量,外部类。
字符串比较用 equals()方法
psw1.equals(psw2); //psw1和psw2字符完全相同则返回true
username.equals("henry"); //区分大小写
Q: equals 和 == 的区别?
A: == 两个对象的地址是否相同;比较两个简单类型值是否相同
equals 比较两个对象的内容是不是完全一样
public String toString() {//需要重写
return "name = "+ name +" age ="+ age;
}
System.out.println("张三",22);//toString()会被自动调用
//extendsdemo.Students@1915376 //包名.类名@hashCode
// ↓
//name = 张三 age =22