>程序中 +号的使用
1.当左右两边都是数值型时,则做加法运算
2.当左右两边有一方为字符串,则做拼接运算
3.运算顺序,是从左到右
System.out.printIn(100+98);//198
System.out.printIn("100"+98)://10098
System.out.printIn(100+3+"hello");//103hello
System.out.printIn("hello"+ 100 +3); //hello1003
>char的输出
char c5 ='b'+ 1;//98+1==>99
System.out.println((int)c5);//99
System.out.println(c5);//99->对应的字符->编码表ASCII(规定好的)=>C
char c = 'a'+1;//不会报错
char ch = c + 1;//会报错
第一种不报错,是因为右边都是常量,编译器在编译的时候会进行自动合并,不做类型转换,编译阶段就完成,不报错。
第二种报错,是因为右边有变量进行运算,编译器不会进行自动合并,所以在运行时进行编译,发现c是变量,char型,1是int型,所以结果转换为int型,所以会报错。
>基本数据类型和String类型的转换
1>基本类型转String类型 【语法:将基本类型的值+“”即可】
2>String类型转基本数据类型 【语法:通过基本类型的包装类调用parseXX方法即可】
public class StringToBasic {
public static void main(String[] args){
//基本数据类型->String
int n1 =100; String s1 = n1 + "";
float f1 = 1.1F; String s2 = f1 + "";
double d1 = 4.5; String s3 = d1 + "";
boolean b1 = true; String s4 = b1 + "";
System.out.println(s1+" "+s2+" "+s3+" "+s4);
//String->对应的基本数据类型
//使用 基本数据类型对应的包装类 的相应方法,得到基本数据类型
String s5 = "123";
int num1 = Integer.parseInt(s5);
double num2 = Double.parseDouble(s5);
float num3 = Float.parseFloat(s5);
long num4 = Long.parseLong(s5);
byte num5 = Byte.parseByte(s5);
short num6 = Short.parseShort(s5);
boolean b = Boolean.parseBoolean("true");
System.out.println(num1+" "+num2+" "+num3+"```");
}
}
>数据类型按精度大小排序
>逻辑运算符
public class PO {
public static void main(String[] args) {
int a = 4;
int b = 9;
//&&短路与 如果第一个条件为false,后面的条件不再判断
if (a < 1 && ++b < 5) {
System.out.println("ok300");
}
System.out.println("a=" + a + "b=" + b); //4 9
//&&短路与 如果第一个条件为false,后面的条件仍会判断
if (a < 1 && ++b < 5) {
System.out.println("ok300");
}
System.out.println("a=" + a + "b=" + b); //4 10
}
}
>标识符命名规范
>键盘输入语句
1)导入该类的所在包,java.util.*
2)创建该类对象(声明变量) Scanner input =new Scanner(System in);
3)调用里面的功能
import java.util.Scanner; //表示把java.util下的Scanner类引入
public class PO {
public static void main(String[] args) {
//1.引入/导入Scanner类所在的包
//2.创建Scanner对象,new创建一个对象
//3.in 就是Scanner类的对象
Scanner in = new Scanner(System.in);
//4.接受用户输入了, 使用相关的方法
System.out.println("请输入名字:");
//5.当程序执行到next方法时,会等待用户输入
String name = in.next(); //接收用户输入字符串
System.out.println("请输入年龄:");
int age = in.nextInt(); //接收用户输入int
System.out.println("请输入薪水:");
double sal = in.nextDouble(); //接收用户输入double
System.out.println("人的信息如下:");
System.out.println("名字="+name+"年龄="+age+"薪水"+sal);
}
}
>进制介绍及其转换
int n1 = 0b1010; //二进制
int n2 = 1010; //十进制
int n3 = 01010; //八进制
int n4 = 0X10101; //十六进制
System.out.println("n1="+n1); //10
System.out.println("n2="+n2); //1010
System.out.println("n3="+n3); //520
System.out.println("n4="+n4); //65793
①二/八/十六进制转十进制
从最低位开始,将每个位上的数提取出来,乘以2/8/16的(位数-1)次方,然后求和。
例:0b1011转成十进制:11
②十进制转二/八/十六进制
将该数不断除以2/8/16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二/八/十六进制。
例:将34转为二进制:0b00100010(一个字节有8位,所以用2个0填充高位)
③二进制转八/十六进制
从低位开始,将二进制数每三/四位一组,转成对应的八/十六进制数即可。
例:将0b11010101转成八进制:0325
④八/十六进制转二进制
将八/十六进制每1位,转成对应的一个3/4位的二进制数即可。
例:将八进制0237转成二进制:0b010011111
>数组初始化
1)在声明的同时初始化,直接确定数组内容,不能再次赋值
int[] arr = {元素};
2)在声明的同时初始化,直接确定元素内容和长度,可以再次赋值
int[] arr = new int[] {元素}
3)在声明的同时初始化,只能确定长度, 内容都为默认值
int[] arr = new int[num]
>数组赋值机制
数组在默认情况下是引用传递,赋的值是地址。
public class PO {
public static void main(String[] args) {
//基本数据类型赋值,赋值方式为值拷贝
//n2的变化,不会影响到n1的值
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1="+n1); //10
System.out.println("n2="+n2); //80
//数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用传达
//是一个地址,arr2的变化会影响到arr1
int[] arr1 = {1,2,3};
int[] arr2 = arr1; //把arr1赋给arr2
arr2[0] = 10;
//让我们来看看arr1的值
for(int i =0; i< arr1.length; i++){
System.out.println(arr1[i]); //10 2 3
}
}
}
可参考:Java中的基本数据类型和引用数据类型的区别 - MaskWolf - 博客园
//编写代码,实现数组拷贝(内容复制),要求数据空间是独立的(例:修改1不影响2)
public class PO {
public static void main(String[] args) {
int[] arr1 = {10,20,30};
//创建一个新的数组arr2,开辟新的数据空间
int[] arr2 = new int[arr1.length];
//遍历arr1,把每个元素拷贝到arr2对应的元素位置
for(int i=0;i < arr1.length; i++){
arr2[i] = arr1[i];
}
//修改arr2,则可发现此时arr2改变不会对arr1造成影响
arr2[0]=100;
for(int i=0;i < arr1.length; i++) {
System.out.println(arr1[i]); //10 20 30
}
for(int i=0;i < arr2.length; i++) {
System.out.println(arr2[i]); //100 20 30
}
}
}
此时:
>二维数组使用细节和注意事项
1)一维数组的声明方式有: int[] x 或者int x[]
2)二维数组的声明方式有: int[][] y 或者 int[] y[] 或者int y[][]
3)二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。
比如:map[][]是一个二维数组 int map [][] ={{1,2},{3,4,5}] .由 map[0]是一个含有两个元素的一维数组,map[1] 是一个含有三个元素的一维数组构成,我们也称为列数不等的二维数组。
>JAVA内存结构分析
1)栈:一般存放基本数据类型(局部变量)
2)堆:存放对象(Cat cat,数组等)
3)方法区:常量池(常量,比如字符串),类加载信息
>对象在内存中存在形式
>类属性注意细节
1)属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;
访问修饰符:控制属性的访值问范围
有四种访问修饰符 public,proctected,private,默认
2)属性的定义类型可以为任意类型,包含基本类型或引用类型
3)属性如果不赋值,有默认值,规则和数组一致。具 体说:int 0,short 0
byte 0, long 0,float 0.0,double 0.0,char \u0000,boolean false,String null
public class DDO {
public static void main(String[] args){
//创建Person1对象
//p1 是 对象名(对象引用)
//new Person1() 创建的对象空间(数据) 才是真正的对象
Person1 p1 = new Person1();
//对象的属性默认值,遵守数组规则
//int 0,short 0,byte 0,long 0,float 0.0,double 0.0,char \u0000,boolean false,String null;
System.out.println("当前这个人的信息");
System.out.println("age="+p1.age+" name="+p1.name+" sal="+p1.sal+" isPass="+p1.isPass);
}
}
class Person1{
int age;
String name;
double sal;
boolean isPass;
}
>方法使用细节
1.一个方法最多有一个返回值 [思考:如何返回多个结果 ->返回数组]
2.返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
3.如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值;而且要求返回值类型必须和return的值类型一致或兼容
4.如果方法是void,则方法体中可以没有return语句,或者 只写 return;
5.方法不能嵌套定义
6.同一个类中的方法调用:直接调用即可。比如: 方法名(参数);
7.跨类中的方法A类调用B类方法:需要通过对象名调用。 比如:对象名.方法名(参数);
public class method1 {
public static void main(String[] args){
AA a = new AA();
int[] res = a.getSumAndSub(1,4);
System.out.println("和="+res[0]);
System.out.println("差="+res[1]);
}
}
class AA{
//1.一个方法最多有一个返回值 [思考:如何返回多个结果? ->返回数组 ]
public int[] getSumAndSub(int n1, int n2){
int[] resArr = new int[2];
resArr[0] = n1+n2;
resArr[1] = n1-n2;
return resArr;
}
}
>增强for语句(循环)
for(声明语句:表达式){
//代码句子
}
public class DD {
public static void main(String[] args){
int[] number={10,20,30,40,50};//定义一个数组
//常规for遍历数组
for (int i = 0; i < 5; i++) {
System.out.println(number[i]);
}
System.out.println("=======================================");
//增强for遍历数组
for (int x:number){ //将number的值赋给x
System.out.println(x);
}
}
}
>成员方法传参机制
1)基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参!
public class DD {
public static void main(String[] args){
int a = 10;
int b = 20;
//创建AA对象 名字 obj
AA obj = new AA();
obj.swap(a,b); //调用swap
System.out.println("main方法\na="+a+" b="+b); //a=10,b=20
}
}
class AA{
public void swap(int a,int b){
System.out.println("\na与b交换前的值\na="+a+"\tb="+b);//a=10,b=20
//完成了a与b的交换
int temp = a;
a = b;
b = temp;
System.out.println("a与b交换后的值\na="+a+"\tb="+b);//a=20,b=10
}
}
2)引用数据类型,传递的是地址(传递也是值,但是值是地址),可通过形参影响实参
public class DD {
public static void main(String[] args){
B b = new B();
int[] arr = {1,2,3};
b.test100(arr);
System.out.println("main的arr数组");
for(int i =0; i<arr.length;i++){
System.out.println(arr[i]+"\t"); //200 2 3
}
System.out.println();
Person2 p = new Person2();
p.name = "jack";
p.age = 10;
A a = new A();
a.test200(p);
System.out.println("main 的 p.age="+p.age); ///10000
}
}
class Person2{
String name;
int age;
}
class A{
public void test200(Person2 p){
p.age = 10000; //修改对象属性
}
}
class B{
public void test100(int[] arr){
arr[0] = 200;
System.out.println("test100的arr数组");
for(int i =0; i<arr.length;i++){
System.out.println(arr[i]+"\t"); //200 2 3
}
System.out.println();
}
}
3)通过例子加深理解
public class DD {
public static void main(String[] args){
Person2 p = new Person2();
p.name = "jack";
p.age = 10;
A a = new A();
a.test200(p);
System.out.println("main 的 p.age="+p.age); ///10
}
}
class Person2{
String name;
int age;
}
class A{
public void test200(Person2 p){
p = null; //修改对象属性
}
}
public class DD {
public static void main(String[] args){
Person2 p = new Person2();
p.name = "jack";
p.age = 10;
A a = new A();
a.test200(p);
System.out.println("main 的 p.age="+p.age); //10
}
}
class Person2{
String name;
int age;
}
class A{
public void test200(Person2 p){
p = new Person2();
p.name = "tom";
p.age = 99;
}
}
>可变参数
>基本概念
java允许将同一个类中多个同名同功能但参数个数不司的方法,封装成一个方法。
>基本语法
访问修饰符 返回类型 方法名(数据类型...形参名){
}
>细节:
1)可变参数的实参可以为0个或任意多个
2)可变参数的实参可以为数组
3)可变参数的本质就是数组
4)可变参数可以和普通类型的参数一起放在形参列表 但必须保证可变参数在最后
5)一个形参列表中只能出现一个可变参数
public class VarParameter {
public static void main(String[] args){
HspMethod m = new HspMethod();
//m.sum();
System.out.println(m.sum(1,3,5));
}
}
class HspMethod{
//1.int...表示接受的是可变参数,类型是int,即可以接收多个int (0-多)
//2.使用可变参数时,可以当做数组来使用 即nums可以当做数组
//3.遍历nums 求和即可
public int sum(int... nums){
//System.out.println("接收的参数个数="+nums.length);
int res = 0;
// for(int i =0;i<nums.length;i++){ //传统for循环
// res += nums[i];
// }
for(int i:nums){ //加强for循环
res = res + i;
}
return res;
}
}
public class VarParameterDetail {
public static void main(String[] args){
//细节:可变参数的实参可以为数组
int[] arr = {1,2,3};
T t1 = new T();
t1.f1(arr);
}
}
class T{
public void f1(int...nums){
System.out.println("长度="+nums.length);
}
//细节:可变参数可以和普通类型的参数一起放在形参列表 但必须保证可变参数在最后
public void f1(String str,double...nums){
}
//细节:一个形参列表中只能出现一个可变参数
// public void f1(String...str,double...nums){
// }
}
>this 关键字使用细节
1.this关键字可以用来访问本类的属性、方法、构造器
2.this用于区分当前类的属性和局部变量
3.访问成员方法的语法:this.方法名(参数列表);
4.访问构造器语法:this(参数列表);注意只能在构造器中使用
5.this不能在类定义的外部使用,只能在类定义的方法中使用
public class ED {
public static void main(String[] args){
//D d1 = new D();
//d1.f2();
D d2 = new D();
}
}
class D{
//细节:访问构造器语法:this(参数列表);注意只能在构造器中使用
// 即只能在构造器中访问另一个构造器
//注意:如果有构造器语法:this(参数列表);必须放置第一条语句
public D(){
this("jack",100);
System.out.println("D()构造器");
//这里去访问D(String name,int age)
}
public D(String name,int age){
System.out.println("D(String name,int age)构造器");
}
//细节:访问成员方法的语法:this+方法名(参数列表)
public void f1(){
System.out.println("f1() 方法..");
}
public void f2(){
System.out.println("f2()方法..");
//调用本类的f1
//第一种方式
f1();
//第二种方式
this.f1();
}
}
>代码块 细节
1)static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行一次。
2)类什么时候被加载
1.创建对象实例时(new)
2.创建子类对象实例,父类也会被加载
3.使用类的静态成员时(静态属性,静态方法)
3)普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。
如果只是使用类的静态成员时,普通代码块并不会执行。
4)创建一个对象时,在一个类 调用顺序是:(重点,难点)
1.调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)
2.调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)调用构造方法。
5)构造器 的最前面其实隐含了 super()和 调用普通代码块,静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优先于构造器和普通代码块执行的.
6)创建一个子类时(继承关系),他们的静态代码块,静态属性初始化普通代码块,普通属性初始化,构造方法的调用顺序如下:
1.父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
2.子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
3.父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
4.父类的构造方法
5.子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
6.子类的构造方法
概括:静态->普通->构造器 父类优于子类
7)静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调
用任意成员。
public class DL {
public static void main(String[] args){
//DDD dd = new DDD();
//DDD dd1 = new DDD();
System.out.println(DDD.n1);//8888,静态代码块一定会执行
}
}
class DDD{
//静态属性
public static int n1 = 8888;
//静态代码块,在new对象时,被调用,而且是每创建一个对象,就被调用一次
static {
System.out.println("DDD 的静态代码块1被执行...");
}
//普通代码块
{
System.out.println("DD 的普通代码块..");
}
}