java----语法基础
java基础:
JDK:java开发环境,包含了java运行环境JRE,java工具以及基础类库。
JRE:java运行环境,大家熟知的JDK不同,JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器),只是针对于使用Java程序的用户。
添加环境变量
JVM:.class文件并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。只有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。
cavaj java decompiler https://cavaj-java-decompiler.en.softonic.com/ java 反编译工具 如果java字节码 进行了加密,就没有用了
javac hellow.java // 编译代码 为.class java字节码 javap -c hellow.class //是字节码容易读 javac -d . HelloWord.java //如果HellowWord.java中有包名,如果需要将包也构建出来,可以使用这个命令 java hellow //运行代码 javadoc Hellowold.java //生成文档 javao -c Helloword.class. //将字节码变成可读
Helloword 代码
/** 文档注释 */ public class Hellowold{ /* 多行注释 Sting[] 为字符串数组 args 字符串数组的名字 */ // 单行注释 public static void main(String[] args){ System.out.println("hello word!"); } }
java中八种数据基本类型
这些变量在方法体中必须要定义和初始化,才可以使用
占字节 默认值 int Integer 4 0 short Short 2 0 long Long 8 0l或0L byte Byte 1 0 float Float 4 0.0F或0.0f double Double 8 0.0 char Character 2 u0000 boolean Boolean 1位(不是一个字节) false
整形变量:011(以0开头的表示8进制),0x11(以0x开头的表示16进行) ,0b11(以0b开头的表示2进制),默认类型是int,比如byte a=11;(11是int类型,被转换了byte)
浮点变量:float尾数可以精确到7位。double:约是float的两倍,默认是dubbo类型,比如float a = 3.14;(会报错,3.14是dubbo类型,用float放不下,所以写3.14F,将3.14转换成float类型),浮点数一般用来比较,比如float a=111111111,float b=111111112,这两个数如果相比较就是true(浮点数是从第一个不为0的数往后数x位来进行比较,在往后面的数据就忽略了),如果需要比较浮点数或者非常大的整数,可以使用java.math包下面的两个有用的类:BigInteger和BigDecimal,这两个类可以处理任意长度的数值。BigInteger实现了任意精度的整数运算。BigDecimal实现了任意精度的浮点运算。
java中引用数据类型
string、数组、接口、类等,占用4个字节(引用对象的地址)
char chr = 127; int sum = 200; chr += 1; sum += chr; 后,sum的值是? 答案:72和328 备注:同时考虑c/c++和Java的情况的话 解释: java中只有byte, boolean是一个字节, char是两个字节, 所以对于java来说127不会发生溢出, 输出328 但是对于c/c++语言来说, char是一个字节, 会发生溢出, 对127加一发生溢出, 0111 1111 --> 1000 0000, 1000 0000为补码-128, 所以结果为200-128=72
基本数据类型转换 (自动转换):
public class Demo { public static void main(String[] args) { byte a = 10; short b = a; int c = b; long d = c; float y = 11; double z = y; //float double 属于近似值 //byte short int 属于精确值 //精确值转换近似值 ,不需要强制转换,可能会丢失精度 int num1 = 21323123; float num2 = num1; //赋值表示将 整数 21323123 赋值给了num2,类似num3 float num3 = 21323123; System.out.println(num2); //2.1323124E7 System.out.println(num3); //2.1323124E7 } }
注意:byte short int 计算时,自动转换 int 类型来比较大小
报错 short t1 = 10; t1 = t1 + 1; // 1 为 int 类型; t1为 short 类型 不能接受 int 类型 ,改为int t2 = t1 + 1 即可 System.out.println(t1); 即使,两个 short 类型相加,同样会报错 short t2 = 1; short t1 = 10; t1 = t1+ t2; //自动转换为 int 类型 没有报错 short t1 = 10; t1 += 1; System.out.println(t1); 没有报错 int t1 = 10; t1 = t1 + 1; System.out.println(t1);
解决:强制转换
short t2 = 1; short t1 = 10; t1 = (short)(t1 + t2); // t1为 short类型接受,将t1+t2,强制转变为short类型 int t3 = (short)(t1+t2),可以,int 本身就可以接受 short 类型的数据 System.out.println(t1);
补充
String 不是基本数据类型 是引用类型变量,32位系统占4个字节,64位占8个字节,对于h = new Horse(); h也是引用类型变量,站的空间是所有属性占的空间之和 String x = "sdfdsf"; //接受一个字符串 char x = 'd'; //接受一个字符 注意:不能使用同一个局部变量,否则会自动转换,如果遇到不能转换的就会报错
java运算:
public class Demo { public static void main(String[] args) { int x=1; int y=2; y = x+y-(++y); //从前往后执行,并不是先 执行括号里面的 System.out.println(x); //1 System.out.println(y); //0;如果(y++)-->1 } }
总结
public class Test { public static void main(String[] args) { //数据比较注意问题 int a =111111; Integer b =111111; System.out.println(a==b); //true Integer和int比较的时候,会将Integer拆成int类型 Integer c =111111; System.out.println(b==c); //false b和c两个对象不一样 b = 127; c = 127; System.out.println(b==c); //true 此时b和c两个对象一样,Integer在-128<= x<=127的整数,将会直接缓存在IntegerCache中。(IntegerCache会缓存一个字节一下的整数) b = new Integer(127); c = new Integer(127); System.out.println(b==c); //false 此时b和c两个对象都是两个新的对象 b = new Integer(127); Integer d = 127; System.out.println(b==d); //false b创建的对象是存放在堆中,和IntegerCache缓存中的d不一样 b = 128; d = 128; System.out.println(b==d); //false IntegerCache不能存放128,所以b和d都相当于new Integer(128) //总结:凡是new Integer(xx),则这两个数肯定是不一样的; //如果使用int=xx,那这两个数肯定是一样的 //如果使用Integer=xx,如果-128<=xx<=127,则这两个数是一样; float x = 11111f; float y = 11111f; System.out.println(x==y); //true Float z = 1f; Float w = 1f; System.out.println(z==w);//false,浮点数不像Integer一样了 //基本数据类型转换注意问题; long aa = 11L; int bb = (int)(aa); Long cc = 11L; //int bb = (int)(cc) 不能转换,cc此时是Long对象了 //基本数据类型相加 int s1=1; int s2=2; int s3 = s1+s2-(s2+++1+s2++); System.out.println(s1); //1 System.out.println(s2); //4 System.out.println(s3); //-3 int a1=1; int a2=2; int a3 = a1+a2-(a2+++1); System.out.println(a1); //1 System.out.println(a2); //3 System.out.println(a3); //0 int b1=1; int b2=2; int b3 = b1+b2-(b2+++1+b2); System.out.println(b1); //1 System.out.println(b2); //3 System.out.println(b3); //-3 int c1=1; int c2=2; int c3 = c1+c2-((c2++)+1+c2++)+c2+c2++; System.out.println(c3);//5 int t = c2++; System.out.println(t);//5 } }
//赋值的时候是从前往后赋值,赋值的操作不会改变前面已经赋值的操作,运算是先算括号中的 int a2=2; //int a3 = (++a2)+a2; //a3=6 //int a3 = a2+(++a2); //a3=5 //int a3 = a2-(++a2+(++a2)); //a3=-5 int a3 = a2-(++a2+(++a2))+ a2++ + (++a2);//a3=5 System.out.println(a3); System.out.println(a2);
java运算符
位运算
>> 带符号右移位
正数移位:右边(低位)移出部分,直接舍弃,左边(高位)移入部分全部补0。(正数的符号为是0)
负数移位:右边(低位)移出部分,直接舍弃,左边(高位)移入部分全部补1。(负数的符号为是1)
<< 带符号左移位
左边(高位)移出部分,直接舍弃;右边(低位)移入部分全部补0。
>>> 无符号右移位
对于正数和0,无符号右移位>>>和带符号右移位>>,结果是一样的
负数移位:右边(低位)移出部分,直接舍弃,左边(高位)移入部分全部补0。(符号为由1变成0,所以负数变正数)
注:java没有 <<< 因为 <<< 就等于 <<
import java.util.Scanner;; public class Demo { public static void main(String[] args) { //以最快的速度进行 64 乘 *8 //64*8=512 速度不够快,位移运算速度最快 short x = 64; System.out.println(x<<3); //512 左移运算 6<<x -->6*2(进制)的x次方 速度最快 System.out.println(-x<<3); //-512 -6<<x -6*2**n System.out.println(x>>3); //8 右移运算 6>>x -->6/ 2(进制)的x次方 System.out.println(-x>>3); //-8 右移运算 -6>>x -->-6/ 2(进制)的x次方 System.out.println(x>>>3); //8 右移运算 6>>>x -->6/ 2(进制)的x次方(正数>>>相当>> 负数>>> 会变成正数且不等于>>) System.out.println(-x>>>3);//536870904左移运算 没有公式 //结果 short int byte 都是 以 int 4个字节运算 } }
注意,如果移动的位数足够大,上面的公式就不管用了,如15<<27= 2013265920 ,15 <<28 = -268435456
15<<32 = 15, 15 << 33 = 30
&做位运算时
A = 0011 1100 == 60 B = 0000 1101 ----------------- A&b=0000 1100 A|B=0011 1101 A^B=0011 0001 异或,相同的为false,不相同的为true ~A= 1100 0011 == -61的补码; ~x=-x
&做逻辑运算时
import java.util.Scanner;; public class Demo { public static void main(String[] args) { Scanner input = new Scanner(System.in); boolean x = true; boolean y = false; boolean z = x&y; System.out.println(z); } }
&的一个重要的用法就是(2x-1)&任何数都是小于(2x-1),比如15--->00000.....1111(二进制)
000000......1111
101001......1011
---------------------------------------
000000......1011 <1111
逻辑运算符
注意
&分别需要计算两边的值;在做判断,效率低;
&& 先计算左边的值,如果为false,直接返回false,效率高
| 和 || 同理;
if分支语句:
if(){ }else if(){ }else{ } if(x==10)--->最好写成if(10==x) //用一个确定的值和不确定的值进行对比, 原因x可能为空,出现空指针的异常
switch分支语句:
//进行两个数据的调换位置 import java.util.Scanner; public class Demo { public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextInt(); switch(n){ case 1:{ System.out.println("星期一"); break; } case 2:{ break; } default:{ System.out.println("没有"); break; } }; System.out.println("结束"); } } 注意jdk 1.7之前不支持 String 即case “sdf”,在1,7之后,支持,原理是编译器在编译的时候将字符串转变成哈希值,int数 case是可以匹配的
注意:如果一旦case相应的值成功,但内部没有break语句,那么将会无条件(不再进行case匹配)的继续向下执行其它case中的语句,直到遇到break;语句或者到达switch语句结束
循环语句:
while(){ } ================== int i=1; do{ System.out.println("先执行一遍"); i++; }while(i<=10); ================= for(;;){ System.out.println("111"); //死循环 } for(int i=0;;i++){ //只要中间没有判断,即为死循环 System.out.println("111"); }
跳出多重循环
public static void main(String[] args) { ok: for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { break ok; } } }
例题:
//进行两个数据的调换位置 public class Demo { public static void main(String[] args) { int a=2; int b=3; //方法一 // int t = a; // a = b; // b = t; //方法二: // a = a+b; // b = a-b; // a = a-b; //方法三: // a = a+b-(b=a); //方法四 速度最快 注意,a 和 b 不能为 同一个 值 否则 a^b =0 a = a^b; b = a^b; a = a^b; System.out.println("a="+a+",b="+b); } }