一、核心语法
1、运算符
-
加法运算
public static void calc(){
int number1 = 20;
double number2 = 21.4;
//1031.5
System.out.printf("num1 + num2 = " + number1 + number2);
}
这段代码输出结果为
2021.4
,原因是因为前面为String
字符串,这里的+
就不在是加法运算符
而是连接符
。
要想输出算数结果代码如下
public static void calc(){
int number1 = 20;
double number2 = 21.4;
//41.4
System.out.printf("num1 + num2 = " + (number1 + number2));
}
输出的算数结果为数据类型更强的
double
型,所以+ - * /
的运算最终结果都为两个或者多个
运算结果中类型最强的那一个类型。
-
2++、-- 运算
public static void calc(){
int count = 1;
System.out.println(count++);
System.out.println(++count);
}
以上代码第一个输出结果为
1
,因为后++
的特性为先用再加
第二条结果为3
,这就是先++
的特性为先加后用
二、变量
程序中的变量就是数据,变量就是内存中数据的代名词。
变量:分配空间存储变量
int a = 5;
1、定义变量需要关注的四个点:
(1)变量的声明:用特定的语法声明一个变量,让其运行环境分配空间的存储。
(2)变量的命名:需要定义见名知意的命名,复合JAVA的命名规范
(3)变量的初始化:变量声明后必须为其赋值才可以使用。
(4)变量的访问:变量可以进行存取操作。
public static void main(String[] args) {
int a =b =10;
}
这样定义变量是不被允许的,因为变量
b
没有声明。
public static void main(String[] args) {
int a =10,b =10; //实际开发中不要使用
int c = b =30;
System.out.println(c);
System.out.println(b);
}
变量
b
被声明后就可以连等赋值。
2、变量名(标识符)
(1)java语言中的标识符:变量、常量、方法、类、包名
(2)标识符的命名规则
1>标识符由大小写字母, 下划线, 数字, 符号.(数字不能开头)
3>标识符长度没有限制
4>标识符不能是关键子和保留字
5>标识符的命名最好能反映出其作用 ,java语言对字母的大小写有严格的要求.所有自定义标识符需全部遵循标识符的命名规范.
5.1变量:
5.1.1>如果是单个单词, 单词全部字母小写. 如:intcount;
5.1.2>如果是由多个单词组成的复合单词, 除第一个单词外, 其后所有单词首字母大写. 如: codeName;
5.2常量 :
常量所有单词字母大写, 如果是由多个单词组成, 由下划线连接.如:String PERSON_NAME;
5.3方法:
方法命名规范与变量相似, 如 count(); getSum();
5.4类:
类名的所有单词首字母均大写. 如Person{} , DataCenter{};
5.5包:
用小写的倒置域名来命名. 格式: 前缀 + 项目名 + 模块名 + 层如: org.itfuture.domain.sorts
3、JAVA变量的分类
-1按声明的位置划分
-1.1局部变量
:方法或语句块内部定义的变量
-1.2成员变量
:方法外部、类的内部的变量
-1.3注意:类外面(与类对应的大括号外面)不能有变量的声明
-2按所属的数据类型分类
-2.1基本数据类型
变量
-2.2引用数据类型
变量
4、JAVA基本数据类型转换
-(1)boolean类型不可以转换为其他数据类型
-(2)整型、字符型、浮点型的数据在混合运算中相互转换,转换遵循一下原则:
-2.1容量小的类型自动转换为容量大的类型:
byte,short,char => int => long => float => double
byte,short,char 之间不会相互转换
,他们三者计算会先转换为int
-2.2 容量大的数据类型转换为容量小的数据类型时,要加上强制转换符,但可能产生精度降低或者溢出;
-2.3 有多种类型的数据混合计算时,系统先自动把所有的数据转换为容量最大的那种数据类型,然后再计算。
-2.4 double转换float时如果产生溢出,会出现Infinity
的情况。
代码第2行就会报错因为小数默认为
double
代码第3行出错l2
如果不加L声明为long
则会溢出编译不通过。
代码第5行b3
溢出
代码第6行变量要先赋值再使用
//出错因为i为`int`型计算结果为`float`型
i=i*0.1
//出错因为b1-b2 结果为int型
byte b = b1-b2;
//报错计算结果为int
char c = c1 + c2 -1;
//报错 计算结果为double
float f4 = f1 + f2 * 0.1
三、面向对象与内存
public class Person {
int id ;
int age;
Person(int id,int age){
this.id = id;
this.age = age;
}
public static void main(String[] args) {
Person person = new Person(2,34);
}
}
上面面向对象的代码内存分析如下图
1.BirthDate.java
生日对象
public class BirthDate {
private int day;
private int month;
private int year;
public BirthDate(int day, int month, int year) {
this.day = day;
this.month = month;
this.year = year;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public String toString() {
return "BiethDate [day=" + day + ", month=" + month + ", year=" + year + "]";
}
}
2.TestBirth.java
函数入口
public class TestBirth {
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
test.change2(birthDate);
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change1(int i) {
i = 1234;
}
public void change2(BirthDate b) {
b = new BirthDate(2, 2, 2002);
}
public void change3(BirthDate b) {
b.setDay(3);
}
}
下面分析以上代码执行过程中内存的变化(此段学习自尚学堂_马士兵_java基础)
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018); //下图为执行到此的内存分配
/*------------------------------------------------------------------------------------*/
test.change1(data);
test.change2(birthDate);
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
如上图当
new TestBirth();
时分配了一个栈内存110925
同指向的堆内存中的一个新对象。
int date = 9
基础类型的数字9。
new BirthDate(6,7,1998);
分配一个栈内存同时,指向堆内存(6,7,1998)
赋值给day month year 。
new BirthDate(1, 1, 2018);
分配一个栈内存同时,指向堆内存(1,1,2018)
赋值给day month year 。
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data); /*-----------执行到这里------------*/
test.change2(birthDate);
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change1(int i) { //先到这里
i = 1234;
}
这个地方
test.change1(data);
相当于实参data
把值复制给了形参i
所以i
的值现在为9
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data); /*-----------执行到这里------------*/
test.change2(birthDate);
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change1(int i) {
i = 1234;//执行到这里
}
data的值并没有发生变化,因为上面只是实参
data
把值复制给了形参i
所以data的值不会变而i
的值变为1234
.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
/*-----------执行到这里------------*/
test.change2(birthDate);
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change1(int i) {
i = 1234;
}//执行到这里
test.change1(data);
方法执行完成之后i
的值消失,因为i为成员变量和局部变量一样执行完之后就会被释放.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
/*-----------执行到这里------------*/
test.change2(birthDate);
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change2(BirthDate b) {//执行到这里
b = new BirthDate(2, 2, 2002);
}
这里和上面有所不同这个地方是实参
b1
吧地址587934
复制给了形参b
,b
指向了堆内存中的对象,和b1指向了同一对象.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
test.change2(birthDate); /*-----------执行到这里------------*/
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change2(BirthDate b) {
b = new BirthDate(2, 2, 2002);//执行到这里
}
当执行到
b = new BirthDate(2, 2, 2002);
可能会有很多人粗心的认为这里会改变原本地址587934
指向的堆内存的值,其实不然这里是new 出来一个新对象所以会产生一个新地址一个新的堆内存.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
test.change2(birthDate);
/*-----------执行到这里------------*/
test.change3(birthDate2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change2(BirthDate b) {
b = new BirthDate(2, 2, 2002);
}//执行到这里
方法执行完毕栈内存中的
形参b被释放
,但是这里堆内存中的对象不一定马上就被释放
,他会等java的垃圾收集器回收内存时将他回收,所以这部分对于我们的代码已经无用所以不用管它,对于我们来说他就已经被回收.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
test.change2(d1);
/*-----------执行到这里------------*/
test.change3(d2);
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change3(BirthDate b) {//执行到这里
b.setDay(3);
}
执行到
test.change3(d2);
这个地方实参b2
吧地址587934
复制给了形参b
,b
指向了堆内存中的对象,和b1指向了同一对象.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
test.change2(d1);
test.change3(d2); /*-----------执行到这里------------*/
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change3(BirthDate b) {
b.setDay(3);//执行到这里
}
public void setDay(int day) {
this.day = day;//执行了这里
}
这个地方又和上面有所不同,这里使用了对象的set方法改变了成员变量day的值,所以只是堆内存中的值发生了变换而不是产生一个新的对象所以堆内存中之前day为
1
现在被set方法把值改为了3
.
public static void main(String[] args) {
TestBirth test = new TestBirth();
int date = 9;
BirthDate d1= new BirthDate(6,7,1998);
BirthDate d2= new BirthDate(1, 1, 2018);
test.change1(data);
test.change2(d1);
test.change3(d2);
/*-----------执行到这里------------*/
System.out.println("data = " + data);
birthDate.toString();
birthDate2.toString();
}
public void change3(BirthDate b) {
b.setDay(3);
}//执行到这里
public void setDay(int day) {
this.day = day;
}//执行了这里
如图所示change3方法执行完毕之后形参b内存被释放,但是堆内存中对象的成员变量day的值被改成了3