java se的那些细节
局部变量:方法体内或语句块内,不能有修饰符
成员变量:与类的对象共存,可以有修饰符
类属性:与类共存,可以有修饰符
一、局部变量:必须先赋值,才能使用,如果不赋初值,则会报错,即没有默认的始使值,而基本数据类型的类属性或成员变量则不会,他们通过编译以后被赋与默认值。
程序1:
public class Test{
public static void main(String[] args){
float f;
System.out.println(f);
}
}
被赋与的值如下:
局部变量: 没有默认值,必须存在值才能使用
属性: javac编译完成后,指定默认值
整数 :0
浮点数:0.0
字符型: \u0000 ''
布尔型: false
引用类型: null
程序2:
public class Test5{
static int a ;
public static void main(String[] args){
float f=0;
System.out.println(f);
System.out.println(a);
new Test();
}
}
class Test6{
int a;
public void Test6(){
System.out.println(a);
}
}
二、尽量不要使用小数比较,原因如下
程序:
public class Test{
public static void main(String[] args){
float f = 0.6f;
double d = 0.6;
System.out.println(f==d);
}
}
double是双精度小数,float是单精度小数,所以得出来的二进制数肯定是不相同的,所以结果为两个相同的数字不相同,如果一定要比较,则按同一类型的小数进行比较。
float和double类型数据可以使用科学记数法表示,如
float f = 3.14e3f---3.14X10的3次方
double f1 = 3.14e-3---3.14X10的负3次方
三、编译期优化:
编译期优化,能够确定结果直接给定结果,不能确定运行确定结果
比如:int a = 3+4;
int b = a+3;
在编译期,a的值就会直接计算出来,而b的值则不会被计算出来,在编译期,只检查第二行的语法是否正确,在运行时才能得出结果。
四、特别容易出错的地方:
short a=3;
short b=3;
short c = (short)(a+b);
这里一定要有强制转换,如果没有强制转换,则会提示错误
第三行即使写成short c = (short)a+(short)b;也是不行的,也会报上面的错误
同理,char和byte也是一样要进行强制转换的。
五、八进制,十六进制
八进制:int a = 033;(在数字前面加个0-零,表示是八进制数)
十六进制:int a = 0x33;(在数字前面加0x-零x,x大小写都可)
六、转义字符(没有办法直接搞出来的)
char 类型用来表示在Unicode编码表中的字符。占两个字节
\\表示的是\
\”表示的是”
\’表示的是’
\n表示的是换行
\t表示的是tab
额外,
public class TestChar {
/**
* @param args
*/
public static void main(String[] args) {
char ch='中';
String s = "中国";
// System.out.println(ch+'\''+"...");
// System.out.println(s+ch);
System.out.println(ch+6+"");
System.out.println(""+ch+6);
}
}
原因:虽然有String类型的时候,输出结果一定为String类型,但是第一个输出的String类型在后面,程序执行前面的时候还是int类型,把结果计算出来以后再往后面执行的时候碰到””才内部强制转换为String类型,而第二个输出则是在开始的时候就碰到String,所以在这以后都是String类型的拼接。这在输出大范围数和小范围数中也同样适用,要把大范围数提前,这样可以避免多次类型转换,也可以防止当前面多个的小范围数据运算时数据溢出。
七、数学余数问题
public class TestYuShu {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(5%(-2));
System.out.println((-5)%2);
System.out.println((-5)%(-2));
System.out.println(5%2);
}
}
输出结果为:
规律:余数的正负与被除数相同,虽然不知道为什么,但还是记下吧,以备以后会用到。
八:a++与++a的问题
程序:
public class TestA {
/**
* @param args
*/
public static void main(String[] args) {
int a = 3;
a=a++;
System.out.println(a);
a=3;
a=++a;
System.out.println(a);
}
}
结果:
将在等号前面的a看成是另外一个int类型的数值b,然后再按照相同的思维把b再符赋值给a,就可以得出上面的结果了。
九:扩展运算符:+= -= *= /= %=
优点:简化了代码,对代码进行了优化:
程序:
public class TestExtend {
/**
* @param args
*/
public static void main(String[] args) {
byte c1=34;
byte c2=56;
c2+=c1;
System.out.println(c2);
c1=34;
c2=56;
c2=(byte)(c2+c1);
System.out.println(c2);
}
}
结果:
从上面的程序可以看出,使用扩展运算符的代码不能进行强制转换了,jdk内容会自动进行转换的,但是如果不用的话,则自己必须进行强制转换,否则编译通不过。
十:逻辑运算符:操作数只能为boolean类型
位运算符(按位运算):& | ~ ^ >> >>> <<<
& | --> 与&& || 区别:
1、普通与 或 所有的表达式都会参与运算
2、可以使用在 int |boolean 上
~ : 取反
^ : 异或 相同为0 ,不同为1
任何整数 ^ 自己 =0
十一、代码的优化:
把当前的工作做好后,看看是否可以对其进行优化,比如减少代码的行数等,或者考虑性能方面的优化。
十二、对象什么时候存在
代码:
Cat cat = null;
Cat cat = new Cat();
对于上面两行代码,第一行并不产生一个对象,只有new了以后才会产生新的对象,因为第一行的代码在只在内存的栈中多了一个引用,这个引用里面的地址为空址,内存的堆中并没有产生对象,只有第二行的代码产生对象。
java内存分析:
栈:用来存放局部变量,引用类型的地址,和基本变量值
堆:存放new出来的对象的
方法区(特殊的堆):用来存储常量,字节码,字符串常量池---即声明的字符串实际存放的位置,声明的任意一个字符串都存在这里。
十三、
构造器是初使化对象信息的特殊方法,不是用来构造对象的,而是给对象里的属性等赋值用的。
例如:
Cat cat = new Cat(“tom”);
在这句话中先在内存的栈中压入cat,占四个字节,然后遇到了new,就在堆中创建了对象,对象里的属性都为默认值,创建好对象以后,碰到了Cat(“tom”),发现它是一个方法,则又在栈中开辟了空间,将这个方法的参数压入栈中,这个参数存的是在方法区(code area)中创建好的字符串tom的地址,然后进行方法里面的操作,这些操作通常是给对象赋值,比如,将tom赋值给新创建对象的属性name等,操作完了以后将其弹出栈,将cat中存入堆中创建对象的地址。
在一个类中,构造方法构成的重载中,如果一个构造器调用了另一个构造器,则调用语句this(…)必须放在这个构造器的第一行,这是语法必须。
十四、protected
java的访问权限:
private
default
protected
public
private只能在自己的类或对象里调用,default则只能在自己的包中调用,不同包的子类也不能调用,protected受保护的则是针对于不同包而言的,同包下可以使用,不同包下的子类也可以使用,public则是不同包下的类也可以访问
但是protected中,对子类可以访问的理解可能会有偏差,类中protected方法是指子类用父类的方法,而不是在子类中父类的对象调用父类。程序如下:
父类:
package com.jll.bjsxt.javase.sixth.homework;
public class Father {
protected void print(){
System.out.println("我是父类打印出来的");
}
}
子类:
package com.jll.bjsxt.javase.sixth.classwork;
import com.jll.bjsxt.javase.sixth.homework.Father;
public class Child extends Father{
public static void main(String[] args){
Child c = new Child();
c.print();
}
}
这样访问是可以的,但是如下访问是不可以的
父类是不变的,子类变化如下:
package com.jll.bjsxt.javase.sixth.classwork;
import com.jll.bjsxt.javase.sixth.homework.Father;
public class Child extends Father{
void p(){
this.print();
}
}
test类如下:
package com.jll.bjsxt.javase.sixth.classwork;
import com.jll.bjsxt.javase.sixth.homework.Father;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Child tp = new Child();
tp.print();
}
}
tp.print()这句话是会出错的,
上面两个例子说明,protected方法子类访问时,只能在子类中访问,不能在不同包的非子类里声明一个子类的对象对它进行访问。
把上面的例子中的child类加一个方法,在这个方法里面调用父类的protected方法,这样,在不同包的非子类中就可以访问这个protected方法了。
十五、方法的重写:
如何找重写
1、程序上
1)、@Override
2)、父类编写方法调用,调用成功 就是重写,否则延续
2、手动上 (面试) 在合理范围 提供子类方法的可见性
1)、前提: 继承 方法签名相同
2)、<=
a)、方法的返回类型
基本类型 |void ==
引用类型 <=
b)、异常<=
每一个方法隐式对外声明一个RuntimeException
子类方法的异常 <=父类方法的异常
c)、可见性 >=
访问修饰符 >=父类 修饰符
四、不会发生重写
1、属性,定义了同名的属性而已,属性就近(从属类)原则
2、以下方法不会重写
1)、静态方法不会重写 ,父类为静态,子类只能为静态,否则编译错误
2)、final修饰方法 否则编译错误
3)、私有方法不会重写
十六、final关键字:
final加在变量前面时,表示这个变量一旦被赋值就不可被改变,如果是final F f =new F()则表示f里面存的地址不可变,f里面的内容是可以改变的,即如果final修饰的是引用类型,则表示引用类型存的地址不可变,引用类型里面的内容可以改变。
如果在一个类中定义了一个成员变量为final,则它的值必须被赋值,赋值的方法有三种:(final int AGE)
1、直接赋值 final int AGE = 10;
2、在构造块中赋值
fina int AGE;
{
AGE = 10;
}
这是因为构造块优先于构造器执行,且每次创建对象的时候都会执行
3、在构造方法中赋值,但是要注意,如果在构造方法中赋值,则必须所有的构造方法中都对其进行赋值,否则编译不通过。原因是不管调用哪个构造器创建对象,这个对象的 final属性都必须有值。如果只对其中一个构造器进行了赋值,则创建对象调用的不是这个,那么就会编译出错
如果在一个类中定义了静态成员变量,也必须对其进行赋值,赋值的二两方法:
1、直接赋值
2、在静态块中赋值,这是因为静态块只在类第一次加载时执行
十七、instanceof
instanceof这个关键字不可乱用,必须用在继承链一条链上使用(不是继承体系),否则编译错误
十八、抽象类
抽象类不能实例化,可以有构造器,这是因为它必须得有子类,当子类调用子类的构造器时,先调用父类的构造器中的一个,任何类都有构造器
十九、java.lang.Cloneable
如果某个类的对象想要被克隆,必须实现java.lang.Cloneable 这个接口,如果不实现这个接口,会报 CloneNotSupportedException运行时异常,这个接口是空的,它的作用是做为克隆的一个标识,如果没有它,则不会被克隆,类似的接口还有一个java.io.Serializable
二十、this super
this与super不能同时存在一个方法中,也不能被用在static静态方法中,原因是this与super都要放在方法的第一行,如果同时存在满足不了它们的要求,而静态方法中是类的对象共享的,不存在对象,当然也不存在this和super.
二十一、
三者联系与区别
* String 不可改变的字符序列 产生大量的垃圾对象 线程安全 equals 比较内容
* StringBuilder 可改变的字符序列 不会产生大量垃圾对象 线程不安全 效率高 没有重写equals 比较地址
* StringBuffer 可改变的字符序列 不会产生大量垃圾对象 线程安全 效率相对低下 没有重写equals 比较地址
StringBuilder和StringBuffer若要比较地址,则要先用toString方法,转换成String,然后再用equals进行比较。
java se的那些细节的更多相关文章
- Java SE 6 新特性: 对脚本语言的支持
2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马).跟 Tiger(Java SE 5)相比,Musta ...
- Java SE 6 新特性: HTTP 增强--转
概述 Java 语言从诞生的那天起,就非常注重网络编程方面的应用.随着互联网应用的飞速发展,Java 的基础类库也不断地对网络相关的 API 进行加强和扩展.在 Java SE 6 当中,围绕着 HT ...
- 黑马程序员 ——Java SE(1)
----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训 ...
- Java SE和Java EE应用的性能调优
凡事预则立,不预则废,和很多事情一样.Java性能调优的成功.离不开行动计划.方法或策略以及特定的领域背景知识.为了在Java性能调优工作中有所成就.你得超越"花似雾中看"的状态, ...
- Java SE教程
第0讲 开山篇 读前介绍:本文中如下文本格式是超链接,可以点击跳转 >>超链接<< 我的学习目标:基础要坚如磐石 代码要十份规范 笔记要认真详实 一.java内容介绍 ...
- java se系列(一)开发前奏
1. 软硬件知识 电子计算机:俗称电脑,是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称为裸机 cpu:是一台计算机的运算核心和控制核 ...
- 数据结构与算法(3)- C++ STL与java se中的vector
声明:虽然本系列博客与具体的编程语言无关.但是本文作者对c++相对比较熟悉,其次是java,所以难免会有视角上的偏差.举例也大多是和这两门语言相关. 上一篇博客概念性的介绍了vector,我们有了大致 ...
- Java SE(1)
Java SE基础回顾 1.循环语句中的break是终止全部循环,跳出循环体:而continue是终止本次循环,跳执行下一循环 2.return语句有两个作用:返回值:结束方法的运行 3.对于java ...
- 【译】Java SE 14 Hotspot 虚拟机垃圾回收调优指南
原文链接:HotSpot Virtual Machine Garbage Collection Tuning Guide,基于Java SE 14. 本文主要包括以下内容: 优化目标与策略(Ergon ...
随机推荐
- Redis 与Spring-data-redis 整合后封装的工具类
此工具类方法是使用了redis 与spring 整合后,才可以使用的工具类,将 spring-data-redis 一些我们开发中常用的方法进行了封装,方便我们日常开发中进行调用: package c ...
- Java_10 继承
1 继承的好处 继承的出现提高了代码的复用性,提高软件开发效率. 继承的出现让类与类之间产生了关系,提供了多态的前提. 2 继承的注意事项 在Java中,类只支持单继承,不允许多继承,也就是说一个类只 ...
- linux命令学习之:sort
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出.sort命令既可以从特定的文件,也可以从stdin中获取输入. 语法 sort (选项) (参数) 选项 sort将文 ...
- maven构建ssh工程
1.1 需求 在web工程的基础上实现ssh工程的创建,规范依赖管理. 1.2 数据库环境 使用之前学习hibernate创建的数据库: 1.3 创建父工程 选择创建Maven Project ...
- materia官网地址
https://materializecss.com/autocomplete.html
- JavaScript 中 如何判断一个元素是否在一个数组中
<script type="text/javascript"> var arrList=['12','qw','q','v','d','t']; console.log ...
- Fastdfs 上传图片
一.fastdfs-client的jar包导入 1.下载地址:https://github.com/happyfish100/fastdfs-client-java 2.将代码使用git下载下来之后, ...
- linux 使用笔记2
安装chrome浏览器在Fedora 23 下载pub wget https://dl-ssl.google.com/linux/linux_signing_key.pub 安装pub sudo rp ...
- git分支切换时的时间戳问题
1.为什么git仓库没有保留文件修改时的时间戳? 摘自:https://git.wiki.kernel.org/index.php/Git_FAQ#Why_isn.27t_Git_preservin ...
- 第一个ASP.NET Web API (C#)程序
本文翻自http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api 绝对手工制作,如有雷同,实属巧合. 转载请注明. ...