讨论this&super这两个关键字的意义和用法。... 4
解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。... 7
Java中关键字continue、break和return的区别:... 12
Scanner 与bufferdRead的区别;... 14
Java各种码 的转化
Java跨平台,但是jvm不跨平台。
· 1、Java中用补码形式表示
2、第一位正负位,1表示负,0表示正。
3、原码:一个数的二进制表示。
3的原码00000011 -3的 原码 10000011
4、反码:负数原码按位取反(符号位不变)。正数原码本身。
3的反码00000011 -3的反码11111100
5、补码:正数是原码本身。负数反码加1。
3的补码是00000011 -3的补码是11111101
-------------------------------------------------------------------------------
int占4个字节,32位
byte占1个字节,8位
所以强转时会截断。前24位
---------------------------------------------------------------------------
在内存中表示形式(注意java中是以补码表示一个数,所以表示形式是补码,不是原码!):
int a = 3 00000000 00000000 00000000 00000011 (强转byte时前面24个0被截断)
byte b = 3 00000011
int a = -3 11111111 11111111 11111111 11111101 (强转byte时前面24个1被截断)
byte b = -3 11111101
----------------------------------------------------------------------------
已知负数的补码,求负数:
补码-1=反码,反码按位取反=该负数绝对值
已知负数,求负数的补码:
1、负数原码除了符号位,按位取反(不含符号位),加1。
2、负数绝对值的补码(也就是原码),按位取反(含符号位),加1
-------------------------------------------------------------------------------
例子:
java int 128转为byte,值:
128为正数,补码为10000000(前面24个0省略),变成byte,只剩下10000000(byte为1个字节),因为开头是1,所以为负数。即1个负数的补码是10000000。反码是01111111,原码是1000000。是128.因为是负数,所以是-128。
a=0000000010000000,当进行强制转换时,byte是八位的,截取a的后八位,b=10000000;最高位是符号位,说明b是负数,在计算机中以补码表示,求其源码,先减1得到反码01111111,取反得到源码10000000,也就是-128.
进制
进制:二进制 (0b开头)
八进制(0开头)
十进制
十六进制(0x开头)
有些字符不能通过键盘输入到字符串或程序,这时候需要转义字符,’\n’:换行,’\b’退格
‘\t’:水平制表 ‘、’’单引号,’\’’’双引号
对于float型:常量后面必须加后缀f或F
基本数据类型的转换:当我们把一个类型的数据赋值给另一个类型的式数据,涉及类型转换,将数据按精度由低到高排序为:byte,short,char,int,long,float,double。当把精度低的变量赋值给精度高的,系统会自动转换。如,float f=100;输出是f为100.0,但是当把级别高的数据赋值给级别的数据则需要数据的类型的强制转化。(类型名)要转化的值
~:取补码的意思
公式-n=~n+1可推出~n=-n-1,所以~10=-11再加5结果为-6
名规则四大类:
package语句是Java源文件的第一条语句。(若缺省该语句,则指定为无名包。),如果想在另一个类里面引用包里面的类,要把名字写全。(相当用文件的绝对路径访问)或者用import导入。
包:文件夹
是以公司的域名反转之后的前两位
www.baidu.com->com.baidu.www->com.baidu
www.edu360.cn->cn.edu360.www->cn.edu360
一个单词:全部小写
多个单词:全部小写,多个单词之间用"."隔开
变量和方法:
一个单词:全部小写 age name show
多个单词:从第二个单词开始首字母大写 readLine showData
类和接口:
一个单词:首字母大写 Person
多个单词:每个单词的首字母大写 InputStream BufferedReader
常量:
一个单词:全部大写 KEY
多个单词:全部大写,每个单词之间用"_"隔开 ROUND_HALF_UP
和字符串做运算:
表达式的运算顺序是从左向右
任何数据和字符串做运算,最终的结果都是字符串
java文档注释:分为描述部分和标记部分
描述部分:描述部分的第一行应该是一句对类、接口、方法等的简单描述,这句话最后会被javadoc工具提取并放在索引目录中。
怎么界定第一句话到哪结束了呢?答案是跟在第一个句号(英文标点)之后的tab、空行或行终结符规定了第一句的结尾。
注释风格:
1. 使用 <code>关键字</code> 来强调关键字,建议强调的内容有:java关键字、包名、类名、方法名、接口名、字段名、参数名等
2. 控制 {@link xxx} 的数量,太多的链接会使文档的可读性很差,因为读者总是跳来跳去。不要出现相同的链接,同样的链接只保留第一个;不要为java自带的内容或是常识性的内容提供链接
3. 描述一个方法时,应当只保留方法名字,不要附带方法的参数。比如有个方法是add(Object obj),那么用add指代该方法即可,而不是add(Object obj)
4. 英文注释可以是短语也可以是句子。如果是句子,首字母要大写,如果是短语,首字母小写。实例如下
*/
标记部分
标记部分跟在描述部分之后,且前面必须有一个空行间隔
常见标记:
1. @author 作者,没有特殊格式要求,名字或组织名称都可以
2. @version 软件版本号(注意不是java版本号),没有特殊格式要求
3. @param 方法参数,格式为: @param 参数名称 参数描述
可以在参数描述中说明参数的类型
可以在参数名称和参数描述之间添加额外的空格来对齐
破折号或其他标点符号不能出现在参数描述之外的地方
4. @return 方法返回值,格式为: @return 返回值描述 ,如果方法没有返回值就不要写@return
5. @deprecated 应该告诉用户这个API被哪个新方法替代了,随后用 @see 标记或 {@link} 标记指向新API,比如
讨论this&super这两个关键字的意义和用法。
在Java中,this通常指当前对象,super则指父类的。
super();必须出现在构造方法的首行. //this();也如此.
当你想要引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利类的某种东西,则非super莫属。
由于this与super有如此相似的一些特性和与生俱来的某种关系,所以我们在这一块儿来讨论,希望能帮助你区分和掌握它们两个。
想要显示的调用父类的构造方法和调用自己构造方法一样,想要调用有参构造方法,那么创建对象时就需要添加参数,无参就正常创建对象。
在一般方法中
最普遍的情况就是,在你的方法中的某个形参名与当前对象的某个成员有相同的名字,这时为了不至于混淆,你便需要明确使用this关键字来指明你要使用某个成员,使用方法是“this.成员名”,而不带this的那个便是形参。另外,还可以用“this.方法名”来引用当前对象的某个方法,但这时this就不是必须的了,你可以直接用方法名来访问那个方法,
Java命名规则:
大驼峰法:多个单词,每个单词的首字母大写
适用对象:类和接口
小驼峰;多个单词,除第一个,其余单词一样首字母大写
使用对象:变量和方法
包命名:用.隔开一般用域名,并且倒过来,如cn.edu.360
也乐意细分到具体的项目名
常量:全部大写字母用下划线隔开,如 KRY_PATH=”/cccc”
Java中有关Null的9件事
对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java。
我越发感到惊奇,因为java的设计原理是为了简化事情,那就是为什么没有浪费时间在指针、操作符重载、多继承实现的原因,null却与此正好相反。好吧,我真的不知道这个问题的答案,我知道的是不管null被Java开发者和开源社区如何批评,我们必须与null共同存在。与其为null的存在感到后悔,我们倒不如更好的学习null,确保正确使用null。
为什么在Java中需要学习null?因为如果你对null不注意,Java将使你遭受空指针异常的痛苦,并且你也会得到一个沉痛的教训。精力充沛的编程是一门艺术,你的团队、客户和用户将会更加欣赏你。以我的经验来看,导致空指针异常的一个最主要的原因是对Java中null的知识还不够。你们当中的很多已经对null很熟悉了,但是对那些不是很熟悉的来说,可以学到一些关于null老的和新的知识。让我们一起重新学习Java中null的一些重要知识吧。
Java中的Null是什么?
就像你创建了一个布尔类型的变量,它将false作为自己的默认值,Java中的任何引用变量都将null作为默认值。
null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型,切记null不能赋值给基本类型
int和Integer有什么区别?
答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Integer里面还有个Max_value的方法,计算int的最大范围
Java 为每个原始类型提供了包装类型:
- 原始类型: boolean,char,byte,short,int,long,float,double
- 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
在Integer中equals()代码类似,有兴趣可以自行去看一下,这里就不重复了。以下是结果分析:
用Short的equals()方法与short进行比较的时候,short类型会被判断为是Short类型的实例,然后两个对象都会被转化为基本类型用==进行比较,所以结果为true。
用==比较Short和short的时候,Short类型对象被拆箱(转为short基本类型),所以结果为true。
用Short的equals()方法与int进行比较的时候,由于类型判断那里就已经为false了,直接返回false。
用Short的equals()方法与Integer进行比较的时候,与用Short的equals()方法与int进行比较的时候同样的原因,返回结果为false。
用==比较Short和int的时候,Short首先是进行了拆箱(转为short基本类型),然后是自动提升类型(转为int),之后才进行比较,所以结果为true。
publicstatic void main(String[] args) {
Integer a =new Integer(3);
Integer b =3; // 将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b); //false 两个引用没有引用同一对象
System.out.println(a == c); // true a自动拆箱成int类型再和c比较
}
}
public classTest03 {
publicstatic void main(String[] args) {
Integer f1= 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1== f2);
System.out.println(f3== f4);
}
} 如果不明就里很容易认为两个输出要么都是true要么都是false。首先需要注意的是f1、f2、f3、f4四个变量都是Integer对象引用,所以下面的==运算比较的不是值而是引用。装箱的本质是什么呢?当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,如果看看valueOf的源代码就知道发生了什么。
简单的说,如果整型字面量的值在-128到127之间,给一个Integer对象赋一个int值的时候,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1==f2的结果是true,而f3==f4的结果是false。
提醒:越是貌似简单的面试题其中的玄机就越多,需要面试者有相当深厚的功力。
Int i=10;
Integer x=new Integer(i);//手动装箱
Integer y=i;//自动装箱如果整型字面量的值在-128到127之间,给一个Integer对象赋一个int值的时候,那么不会new新的Integer对象
Integer j=new Integer(8);//定义一个Integer包装类对象,值为8
Int m=j.intValve();//手动拆箱
Int n=j;//自动拆箱
自动装箱:把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质,可以调用toString()、hashCode()、getClass()、equals()等方法在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和ReferenceType(引用类型)。基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法。所以Java提供了针对每种基本类型的包装类型。如下:
Java基本数据类型 | |||||
INDEX | 基本类型 | 大小 | 数值范围 | 默认值 | 包装类型 |
1 | boolean | --- | true,false | false | Boolean |
2 | byte | 8bit | -2^7 -- 2^7-1 | 0 | Byte |
3 | char | 16bit | \u0000 - \uffff | \u0000 | Character |
4 | short | 16bit | -2^15 -- 2^15-1 | 0 | Short |
5 | int | 32bit | -2^31 -- 2^31-1 | 0 | Integer |
6 | long | 64bit | -2^63 -- 2^63-1 | 0 | Long |
7 | float | 32bit | IEEE 754 | 0.0f | Float |
8 | double | 64bit | IEEE 754 | 0.0d | Double |
常用的基本进制转换:
public static String toBinaryString(int i)
public static String toOctalString(int i)
public static String toHexString(int i)
十进制到其它进制: public static String toString(int i,int radix)
由于测试出了进制的范围:2-36
为什么呢?0,...9,a,...z
其它进制到十进制:
public static int parseInt(String s,int radix)
Chacter常用方法
isLowerCase()
isUpperCase()
isDigit()//判断是否为数字
isDefined()确定字符是否为Unicode字符
isLetter()是否为字母
isSpaceChar()是否为Unico空白字符
isWhitespace()根据JAVA标准是否为空白字符
所以以后判断字符类的情况使用Character比较合适
解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。
答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在静态区中。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。
编译
编译型语言在程序执行之前,有一个单独的编译过程,将程序翻译成机器语言,以后执行这个程序的时候,就不用再进行翻译了。 2.解释型语言,是在运行的时候将程序翻译成机器语言,所以运行速度相对于编译型语言要慢。 3.C/C++ 等都是编译型语言,而Java,C#等都是解释型语言。 4.虽然Java程序在运行之前也有一个编译过程,但是并不是将程序编译成机器语言,而是将它编译成字节码(可以理解为一个中间语言) 5.脚本语言一般都有相应的脚本引擎来解释执行。 他们一般需要解释器才能运行。JAVASCRIPT,ASP,PHP,PERL,Nuva都是脚本语言。C/C++编译、链接后,可形成独立执行的exe文件。
JDK,JRE,JVM区别与联系?
答: jdk包含jre包含jvm
JDK: Java Development ToolKit(Java开发工具包)。JDK是整个JAVA的核心,包括了Java运行环境(JavaRuntime Envirnment),一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。最主流的JDK是Sun公司发布的JDK,除了Sun之外,还有很多公司和组织都开发了属于自己的JDK,例如国外IBM公司开发了属于自己的JDK,国内淘宝也开发了属于自己的JDK,各个组织开发自己的JDK都是为了在某些方面得到一些提高,以适应自己的需求,比如IBM的JDK据说运行效率就比SUN的JDK高的多。但不管怎么说,我们还是需要先把基础的Sun JDK掌握好。 JDK有以下三种版本: J2SE,standardedition,标准版,是我们通常用的一个版本J2EE,enterpsiseedtion,企业版,使用这种JDK开发J2EE应用程序J2ME,micro edtion,主要用于移动设备、嵌入式设备上的java应用程序 我们常常用JDK来代指Java API,Java API是Java的应用程序接口,其实就是前辈们写好的一些java Class,包括一些重要的语言结构以及基本图形,网络和文件I/O等等 ,我们在自己的程序中,调用前辈们写好的这些Class,来作为我们自己开发的一个基础。当然,现在已经有越来越多的性能更好或者功能更强大的第三方类库供我们使用。 JRE:Java Runtime Enviromental(java运行时环境)。也就是我们说的JAVA平台,所有的Java程序都要在JRE下才能运行。包括JVM和JAVA核心类库和支持文件。与JDK相比,它不包含开发工具——编译器、调试器和其它工具。 JVM:Java VirtualMechinal(JAVA虚拟机)。JVM是JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 的主要工作是解释自己的指令集(即字节码)并映射到本地的 CPU 的指令集或 OS 的系统调用。Java语言是跨平台运行的,其实就是不同的操作系统,使用不同的JVM映射规则,让其与操作系统无关,完成了跨平台性。JVM 对上层的 Java 源文件是不关心的,它关注的只是由源文件生成的类文件( class file)。类文件的组成包括JVM 指令集,符号表以及一些补助信息。
JVM的内存空间:
(1). Heap 堆空间:分配对象 new Student()
(2). Stack 栈空间:临时变量 Student stu
(3).Code 代码区 :类的定义,静态资源 Student.class
Studentstu = new Student(); //new 在内存的堆空间创建对象
stu.study(); //把对象的地址赋给stu引用变量
Student stu =
newStudent
();
//new 在内存的堆空间创建对象
stu.study();
//把对象的地址赋给stu引用变量
上例实现步骤:
a.JVM加载Student.class 到Code区
b.new Student()在堆空间分配空间并创建一个Student实例
c.将此实例的地址赋值给引用stu,栈空间
Java保留字:goto,coast
Java 运算符
1 前加加 如++A 后加加 A++ 注:单独使用不做运算时(一般不用)没有区别 都是加一;但是一旦牵涉别的如运算,括号都有: 前加加 先加后运算,后加加先运算在加1;例如
Int a=4;
Int b=(a++)+(++a)+(a*10); 此时 b=70;因为(a++)=4,出了括号a+1变成5,(++a)=6 a变成6 *10=60
2.取余:java中是 % ,17%4=1 取整是/,17/4=4
如果想要得到准确的数用double或folat
rem(3,2)=1
rem(-3,-2)=-1
rem(3,-2)=1
rem(-3,2)=-1
取余得到的值和被除数的符号一样
2.取模
mod(3,2)=1
mod(-3,-2)=-1
mod(3,-2)=-1
mod(-3,2)=1
取模得到值的符号与除数(后面的数)的符号一样
由此可以看出,rem和mod是有符号区别的!
当除数与被除数的符号相同时,rem和mod的结果是完全相同的;当除数与被除数的符号不相同时,结果不同。
3.int a=10;int b=10;b+=a;//b=b+a; 加等于或其他运算等于有强制转化的功能。
如 short s=1;
s=s+1;//错误,因为把int类型赋值给了short类型。
但是s+=1;//没问题,因为s+=1;想爱你相当于s=(short)(s+1);
算数运算符:+ - * / % ++ --
关系运算符:== != > >= < <=
逻辑运算符:&& || ! ^ & |
位运算符:& | ~ ^ >> << >>>
双逻辑运算符&&,||与单逻辑运算符的区别:
&&与||如果前面判断满足条件后面的就不再运算,而&和|什么时候都全部运算完
面试题可能会考 例如:int x=3,y=4;
System.out.print((x++>3)&(y++>4));此时也会判断(y++>4)
但是:System.out.print((x++>3)&&(y++>4));就判断不到(y++>4)
需要注意 ==
==运算比较的不是值而是引用,equals()比较的是内容,new出来的对象存在堆中
运算符的优先级
单目乘除为关系,逻辑三目后赋值。
单目:单目运算符+ –(负数) ++ -- 等
乘除:算数单目运算符* / % + -
为:位移单目运算符<< >>
关系:关系单目运算符> < >= <= == !=
逻辑:逻辑单目运算符&& || & | ^
三目:三目单目运算符A > B ? X : Y
后:无意义,仅仅为了凑字数
赋值:赋值=位运算符:
位运算是以二进制位为单位进行的运算,其操作数和运算结果都是整型值。
位与'&':对应的二进制数都为1和才为1否则为0。
位或'|':只要有一个为1就为1 ,全为0才为0
位非'~':对应取反。
位异或'^':a,b对应的位相同则为0,否则为1
异或( xor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:
a⊕b = (¬a ∧ b) ∨ (a ∧¬b)
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位
右移'>>',左移'<<',0填充的右移'>>>'
位运算的位与'&',位或'|',位非'~',位异或'^'与逻辑运算的相应操作的真值表完全相同,其差别只是位运算操作的操作数和运算结果都是二进制整数,而逻辑运算相应操作的操作数和运算结果都是逻辑值boolean型。
左移运算符
混合赋值运算符的使用
<<表示左移位
>>表示带符号右移位
>>>表示无符号右移
但是没有<<<运算符因为<<后右边总是补0
1)它的通用格式如下所示:
value << num
num 指定要移位值value 移动的位数。
左移的规则只记住一点:丢弃最高位,0补最低位
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了332=1位。
2)运算规则
按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;
当左移的运算数是long 类型时,每移动1位它的第63位就要被移出并且丢弃。
当左移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
3)数学意义
在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
4)计算过程:
例如:3 <<2(3为int型)
1)把3转换为二进制数字00000000 0000 0000 0000 0000 0000 0011,
2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,
3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,
转换为十进制是12。
移动的位数超过了该类型的最大位数,
右移运算符
右移运算符<<使指定值的所有位都右移规定的次数。
1)它的通用格式如下所示:
value >> num
num 指定要移位值value 移动的位数。
右移的规则只记住一点:符号位不变,左边补上符号位
2)运算规则:
按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1
当右移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
例如,如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension ),在进行右移
操作时用来保持负数的符号。
3)数学意义
右移一位相当于除2,右移n位相当于除以2的n次方。
4)计算过程
11 >>2(11为int型)
1)11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011
2)把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。
3)最终结果是0000 0000 0000 0000 0000 0000 0000 0010。
转换为十进制是2。
35 >> 2(35为int型)
35转换为二进制:0000 0000 0000 0000 0000 0000 0010 0011
把低位的最后两个数字移出:00000000 0000 0000 0000 0000 0000 1000
转换为十进制: 8
5)在右移时不保留符号的出来
右移后的值与0x0f进行按位与运算,这样可以舍弃任何的符号位扩展,以便得到的值可以作为定义数组的下标,从而得到对应数组元素代表的十六进制字符。
Java中关键字continue、break和return的区别:
continue:跳出本次循环继续下一次循环
break: 跳出循环体,继续执行循环外的函数体
return: 跳出整个函数体,函数体后面的部分不再执行,如果下面还有函数执行下一个。
有代码才有真相:
[java] view plain copy
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">public class JavaBese {
public static void main (String[] args) {
int j = 3;
for (int i = 0; i < 5; i++) {
if (i == j) {
continue;
}
System.out.println("i = " + i);
}
System.out.pintln("循环结束");
}
}</span></span>
打印结果为:
i = 0
i = 1
i = 2
i = 4
循环结束
如果是break,打印结果为:
i = 0
i = 1
i = 2
循环结束
如果是return,打印结果为:
i = 0
i = 1
i = 2
二、其他用途
break和continue可以配合语句标签使用。
Java中的return语句使用总结
Java中的return语句总是和方法有密切关系,return语句总是用在方法中,有两个作用,一个是返回方法指定类型的值(这个值总是确定的),一个是结束方法的执行(仅仅一个return语句)。
在return语句的各类文章中,大多仅仅介绍了return语句用于有返回值(非void返回值)的方法中。而很少或没有介绍return语句在void返回值方法中的运用。
return语句用在非void返回值类型的方法中,不但能返回基本类型,还可以返回(包括用户自定义类的)对象
三种循环语句的不同和使用场景
while和for的区别:当循环结束之后,初始化变量还需要继续访问就使用while;如果不需要继续使用就用for,因为for语句结束之后
在for循环的初始化语句初始化的变量都会消失
while和for语句的循环体语句想要执行,必须是判断条件语句返回true才可以
do...while语句不论判断条件是true还是false都会至少执行一次
for:更适合做固定范围内的循环
while:更适合求未知数的循环
do...while:更适合至少循环体语句需要被执行一次的循环
7.跳转控制语句
break:中断语句的意思,可以中断switch语句和所有的循环语句;离开使用场景没有任何意义
continue:结束本次循环,直接开始下一次循环;可以结束所有的循环语句;离开使用场景没有任何意义
return:结束当前的方法并将执行权交给上层调用者
Scanner 与bufferdRead的区别;
Scanner类用法
Scanner是SDK1.5新增的一个类,可使用该类创建一个对象。
Scanner reader=new Scanner(System.in);
然后reader对象调用下列方法(函数),读取用户在命令行输入的各种数据类型
next.Byte(),nextDouble(),nextFloat,nextInt(),nextLine(),nextLong(),nextShot()
上述方法执行时都会造成堵塞,等待用户在命令行输入数据回车确认.例如,拥护在键盘输入12.34,hasNextFloat()的值是true,而hasNextInt()的值是false。NextLine()等待用户输入一个文本行并且回车,该方法得到一个String类型的数据。
hasNextXXX():用来判断输入的类型是否是需要的类型,如hasNextInt(),判断是否为整形
Scanner的构造器支持多种方式,可以从字符串(Readable)、输入流、文件等等来直接构建Scanner对象,有了Scanner了,就可以逐段(根据正则分隔式)来扫描整个文本,并对扫描后的结果做想要的处理。
下面是一些API函数的用法:
delimiter()
返回此 Scanner 当前正在用于匹配分隔符的Pattern。
hasNext()
判断扫描器中当前扫描位置后是否还存在下一段。(原APIDoc的注释很扯淡)
hasNextLine()
如果在此扫描器的输入中存在另一行,则返回 true。
next()
查找并返回来自此扫描器的下一个完整标记。
nextLine()
此扫描器执行当前行,并返回跳过的输入信息。
System.in提供的 read方法每次只能读取一个字节的数据,而我们平时所应用的通常是读取一个字符串或者是一个数字,所以read方法所以提供的功能,对我们来说并没有太大的用处. 用Scanner获得用户的输入非常的方便,但是Scanner取得输入的依据是空格符,包括空格键,Tab键和Enter键.当按下这其中的任一键时,Scanner就会返回下一个输入. 当你输入的内容中间包括空格时,显然,使用Scanner就不能完整的获得你输入的字符串.这时候我们可以考虑使用BufferedReader类取得输入.其实在Java SE 1.4及以前的版本中,尚没有提供Scanner方法,我们获得输入时也是使用BufferReader的.
BufferedReader类位于java.io包中,所以要使用这个类,就要引入java.io这个包:import java.io.BufferedReader.
使用BufferedReader对象的readLine()方法必须处理java.io.IOException异常(Exception).
使用BufferedReader来取得输入,理解起来要复杂得多.但是使用这个方法是固定的,每次使用前先如法炮制就可以了.
BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
String text = buffer.readLine();
readLine()方法会返回用户在按下Enter键之前的所有字符输入,不包括最后按下的Enter返回字符.
数据类型与特点
1. 1byte=8bit(位),因为一位存储一个二进制数因此有两种可能 所以nbit有2^个数,计算基准储存的时补码,正数的所有码都一样,负数:反码:符号位不变其余取反,补码:在反码的基础的上末尾数加1。
2. 数据字节不同的目的:提高对存储空间的利用,正数默认类型为int,小数默认类型为double,folat常量末尾加上f,long:当范围超过int的范围,末尾加上L 。重点char:两个字节,char如果不运算就表示一个字符,一旦牵涉运算就表示ASSII码,当然加减乘除都行;char的默认值是\u000,在Java中表示一个char常量的时候,可以使用\u转义字符来表示一个CU——这里需要注意的是,使用\u来表示一个char常量的时候,必须使用四位的十六进制数。例如 '\u0012',这样才符合一个char类型变量必须为16-bit的要求。如果写成'\u12'字符串和任何类型相加结果都是字符串,float最大范围要比long的最大范围大,+严格从左到右运算,小范围的数值可以赋值给大范围的,反之则不行。在Short和byte的范围内的值都可以赋值给short和byte的变量。bolean类型的数据不能和基本类型运算不,但是引用类型可以 String就可以
3. 基本数据类型的级别,byte>short>char>int>long>float>double,原理其实就是范围大的转化成范围小的有可能导致数据丢失。
4. float=n;n如果是小数必须加f;因为小数的默认类型为double
n如果为整数,加不加f都行。
5. 1byte=8bit(位),因为一位存储一个二进制数因此有两种可能所以nbit有2^个数,计算基准储存的时补码,正数的所有码都一样,负数:反码:符号位不变其余取反,补码:在反码的基础的上末尾数加1。
6. 数据字节不同的目的:提高对存储空间的利用,正数默认类型为int,小数默认类型为double ,folat常量末尾加上f,long:当范围超过int的范围,末尾加上L 。重点char:两个字节,char如果不运算就表示一个字符,一旦牵涉运算就表示ASSII码,当然加减乘除都行;char的默认值是\u000,在Java中表示一个char常量的时候,可以使用\u转义字符来表示一个CU——这里需要注意的是,使用\u来表示一个char常量的时候,必须使用四位的十六进制数。例如 '\u0012',这样才符合一个char类型变量必须为16-bit的要求。如果写成 '\u12'字符串和任何类型相加结果都是字符串,float最大范围要比long的最大范围大,+严格从左到右运算,小范围的数值可以赋值给大范围的,反之则不行。在Short和byte的范围内的值都可以赋值给short和byte的变量。bolean类型的数据不能和基本类型运算不,但是引用类型可以 String就可以
7. 基本数据类型的级别,byte>short>char>int>long>float>double,原理其实就是范围大的转化成范围小的有可能导致数据丢失。
8. 强制转换:当级别高的数据赋值或转化成级别低的数据时:需要强制转化。
9. Utf—8一个汉字3个字节 gbk一个汉字2个字节 Unicode 一个汉字2个字节
10. 1字符=2字节,1字节=8位
11. 英文和数字占一个字节,中文占一个字符,也就是两个字节
Java语言中,中文字符所占的字节数取决于字符的编码方式,一般情况下,采用ISO8859-1编码方式时,一个中文字符与一个英文字符一样只占1个字节;采用GB2312或GBK编码方式时,一个中文字符占2个字节;而采用UTF-8编码方式时,一个中文字符会占3个字节。因为java内部都是用unicode的,所以java其实是支持中文变量名的,比如string 世界 = "我的世界";这样的语句是可以通过的。
综上,java中采用GB2312或GBK编码方式时,一个中文字符占2个字节,而char是2个字节,所以是对的
默认值:
基本类型 | 默认值 |
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
char | '\u0000' |
boolean | false |
12.
13. float占4个字节为什么比long占8个字节大呢,因为底层的实现方式不同。
浮点数的32位并不是简单直接表示大小,而是按照一定标准分配的。
第1位,符号位,即S
接下来8位,指数域,即E。
剩下23位,小数域,即M,取值范围为[1 ,2 ) 或[0 , 1)
然后按照公式: V=(-1)^s * M * 2^E
也就是说浮点数在内存中的32位不是简单地转换为十进制,而是通过公式来计算而来,通过这个公式虽然,只有4个字节,但浮点数最大值要比长整型的范围要大。
14. 强制转换:当级别高的数据赋值或转化成级别低的数据时:需要强制转化。
15. Boolean类型命名规则:一般以is,has等开头,如 isVip,isEmpty。
16. 不同类型的数据进行运算,级别低的先转成级别高即是先转化为同一类型,然后进行运算
17. 空格控制符;
控制语句
1.如果if不加{}则第一个分号为止。
2.switch(表达式)表达式必须是 byte。Short,int,char,jdk1.7后也支持String
Switc只有遇到break才停止 ,即使条件不匹配
循环语句
1.遗忘点:while后面必须自增或自减变量;
2.While()括号内变量值的确定 ,用相反范围。如至少攒够1024反过来就是小于2014.
3.For循环绝不仅仅是加加 减减,条件2(中间的条件)可以是各种形式只要满足boolean,比如求一个十进制的二进制
for (int n=i;n>0 ;n=n/2 ){
sum=sum+n%2*j;
j=j*10;
}
System.out.println(sum);
在Java中,或者在编程中(其实C语言和其它语言也有大致雷同用法),break有三种用法,其中的两种非常常用,就是switch语言的break终止和循环语句中(for,While,do While)的break跳出循环。第三种不常用,就是做为“goto“语句跳到指定位置。
public class forDemo3 {
public static void main(String[] args){
first:for(inti=0;i<=10;i++){
for(intj=0;j<=i;j++){
System.out.print(j+" ");
if(j==5){
break first;
}
}
System.out.println();
}
}
}
4.do-while()意思是只要满足while括号内的就继续执行;
5. JAVA语言规范规定不允许一个本地变量声明语句作为一条语句在for 、while 、do while 循环中重复执行
// 一个本地变量声明作为一条语句只能直接出现在一个语句块中(一个语句块是由一对花括号以及包含在这对花括号以及包含在这对花括号中的语句和声明构成的,)
//
//
// 下面的这种也是错误的。
//
// for(int i=0;i<44;i++)
// int a =3;
循环比较:
1.do...while循环至少执行一次循环体.
2.而for,while循环必须先判断条件是否成立,然后决定是否执行循环体语句.
Static
当类加载时,static静态方法随着类加载而初始化,此时实例对象还未被创建,但是非静态成员变量需要等到实例对象创建才会被初始化,故无法被引用。
静态方法中不能使用this,因为静态方法优先于对象的创建
Static变量属于类的,又所有的对象共享,这样创建多个类的时候,共享的数据不需要重新赋值创建时就有了,比如汽车的logo,都一样所以用static修饰。
方法中调用另一个方法
在同一个类中:
对于静态方法,其他的方法(静态或非静态)方法都可以直接调用它。
不是的静态方法,只有不是静态方法是可以直接调用它的,静态方法只有通过对象才能调用它。
总结一句:在同一个类中,也就是静态方法不可以调用非静态方法;非静态方法可以调用任何方法(静态非静态)。
不同类中:
不同的类之间,无论调用方法是非静态还是静态,如果被调用的方法是:
静态方法,则通过类名与对象都可以调(但通过对象的方式不建议使用,因为它属于非静态调用的方式)
非静态方法,则只能通过对象才可以调用它
静态方法不可以调非静态全局变量
从内存的角度看,就是当类被加载的时候静态方法和静态属性(全局静态变量)被加载到内存中,就是在内存中开辟一段内存地址用来保存静态方法和静态属性,这时候没有被实例化的类在内存中是不存在的,所以静态方法是不能访问非静态的全局变量,在类被实例化的时候,就是new 某个类的时候,在内存中给这个类开辟一些内存空间保存这个类的对象,这个时候就可以用静态方法去访问非静态的全部变量
static变量能不能再赋值
static变量在编译时已经分配内存,
定义static变量是称为静态变量 也是全部变量
谁说全局就不能改变值了
除非是 static final声明,就成常量了,就不能改了
Java随机数的产生方式
在Java中,随机数的概念从广义上将,有三种。
1、通过System.currentTimeMillis()来获取一个当前时间毫秒数的long型数字。
2、通过Math.random()返回一个0到1之间的double值。
3、通过Random类来产生一个随机数,这个是专业的Random工具类,功能强大。
· 其中Math.random()方法是一个可以产生[0.0,1.0]区间内的一个双精度浮点数的方法
如:
产生一个100以内的整数:int x=(int)(Math.random()*100);
又如:
产生一个1-50之间的随机数(需要强制转换):int x=1+(int)(Math.random()*50)
· 也可以使用通用创建对象来获取:
Randomrandom = new Random();
random.nextInt(x);产生一个0到x-1的正数,其他方法需要乘以X-1。
产生一个0到x-1的正数,如果想产生浮点数有Random类的nextFloat方法,总之nextXXX方法是用来产生随机数的、
控制小数点后的位数;BigDecinal
BigDecimalmData = new BigDecimal(d).setScale(n, BigDecimal.ROUND_HALF_UP);
n是小数点后的尾数
d是要控制的小数
如BigDecimal mData = new BigDecimal(1.22222).setScale(2,BigDecimal.ROUND_HALF_UP);
输出1.22
若设置随机种子则相同的种子,产生的随机数相同。若不设置则每次随机的不同。
Randomrnd = new Random();
rnd.setSeed()用于设置种子。
rnd.nextInt()用于产生随机数。
rnd.nextInt(10);// 0-10之间。
变量;成员变量,局部变量
java中,类的成员变量不用初始化即可直接使用,JVM会自动初始化使用默认值,如int char short long byte默认为0,float double默认为0.0,boolean初始化为false,对象初始化null
成员变量和局部变量的区别
成员变量:
①成员变量定义在类中,在整个类中都可以被访问。
②成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
③成员变量有默认初始化值。
局部变量:
①局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
②局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
③局部变量没有默认初始化值
在使用变量时需要遵循的原则为:就近原则
成员变量的隐藏:
在方法中如果类变量和局部变量名字一样,此时成员变量就被隐藏了,如果想使用类变量,则必须使用this因为this调用的是类变量
首先在局部范围找,有就使用;接着在成员位置找。
由static修饰的变量称为静态变量,其实质上就是一个全局变量。如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。
实体:
堆(heap)是一种运行时的数据结构,是一个大的存储空间,用于支持动态的内存管理。Java的对象在堆中分配内存,对象的引用在栈(stack)中。
当类创建对象时,类中的成员变量在堆中分配内存,这些内存空间叫做该对象的实体或对象的变量。对象中存放着引用(对象在内存的名字),该引用在栈(stack)中分配内存,以确保该实体有该对象操作使用。
引用类型的传递,不是值而是传递的引用。
Print p1=new Print(12,18); Print p1=new Print(6,8);
P1 p2
12,16 p1引用的实体
0xab是p1在内存中的名字
6,8 p2引用的实体 0xdd是p1在内存中的名字
如果 p1=p2;也就是此时p1和p2的引用一样了所引用的是同一个实体6,8
基本类型参数传递(值传递):
方法的到的参数都是变量的副本,副本的改变不会影响变量的值
也就是所谓的java值传递
对比一下两题
例1
public class Snippet { public static void main(String[] args) { MyObj obj = new MyObj(); System.out.println(obj.age); process(obj); System.out.println(obj.age); }
private static void process(MyObj obj){ obj.age = 20; }
static class MyObj{ private int age = 10; }
} |
上面的代码结果大家肯定都明白:10 20。
例2
public
class
SendValue{
public
Stringstr="6";
public
static
void
main(String[]args) {
SendValuesv=new
SendValue();
sv.change(sv.str);
System.out.println(sv.str);
}
public
void
change(Stringstr) {
str="10";
}
}
结果;6
例1传递的是对象,改变了对象的变量值,而例2传递的是变量,方法得到的是变量的副本
故,变量的真正值不变。
Final主要用法
Final修饰的类不能被继承
Final修饰的额变量的值不能改变
Final修饰的方法不能被重写
Final修饰成员变量时一定要在对象初始化之前对变量赋值,可行的方法有:
1, 构造代码块(除了静态代码块)
2, 直接赋值
3, 构造方法
Final修饰的局部变量在使用之前要提前赋值
Final修饰引用类型时地址值不变但是地址对应的内存存储的东西可以变
Final修饰的变量或方法通常加上static,因为final表示不变了,放在静态去就行了,这样省内存空间