(002) java后台开发之对象初始化
class Default{
boolean t;char c;byte b;short s;int i;long l;float f;double d;public void show() {System.out.println("基本类型 初始化值\n"+"boolean<----->" + t +"\n" +"char<----->" + c +"\n" +"byte<----->" + b + "\n" +"short<----->" + s + "\n" +"int<----->" + i + "\n" +"long<----->" + l + "\n" +"float<----->" + f + "\n" +"double<----->" + d + "\n");} } public class InitValue {public static void main(String[] args) {Default d = new Default();d.show();} }
【运行结果】:
基本类型 初始化值
boolean<----->false
char<----->
byte<----->0
short<----->0
int<----->0
long<----->0
float<----->0.0
double<----->0.0
其中,char类型的默认值为空(null)。
对于非基本数据类型而言,对象的句柄也会被初始化:
class Person {private String name;// setter } class Default {Person p;public void show() {System.out.println("Person<----->" + p);} } public class InitValue {public static void main(String[] args) {Default d = new Default();d.show();} }
【运行结果】:
Person<----->null
可见,句柄初始化值为null。这就是说,如果没有为p指定初始化值就调用类似于p.setName
的方法,就会出现异常。
规定初始化
如果需要自己为变量赋一个初始值,可以在定义变量的同时赋值。
class Default{boolean t = true;char c = 'A';byte b = 47;short s = 0xff;int i = 24;long l = 999;float f = 1.2f;double d = 1.732;public void show() {System.out.println("boolean<----->" + t +"\n" +"char<----->" + c +"\n" +"byte<----->" + b + "\n" +"short<----->" + s + "\n" +"int<----->" + i + "\n" +"long<----->" + l + "\n" +"float<----->" + f + "\n" +"double<----->" + d + "\n");} } public class InitValue {public static void main(String[] args) {Default d = new Default();d.show();} }
甚至可以通过一个方法来进行初始化;
class Person {int i = set();//... }
这些方法也可以使用自变量:
class Person {int i;int j = set(i);//... }
构建器初始化
构建器进行初始化的优点是可以在运行期决定初始化值。例如:
class Person {int age;Person() {age = 89;} }
age首先会初始化为0,然后变成89。对于所有基本类型以及对象的句柄,这种情况都是成立的。
初始化顺序
在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那么变量仍然会在调用任何方法(包括构造函数)之前得到初始化。例如:
class Pet {Pet(int age) {System.out.println("Pet(" + age + ")");} }class Person {Pet t1 = new Pet(1);Person() {System.out.println("---Person()---");t3 = new Pet(33);}Pet t2 = new Pet(2);void show() {System.out.println("show----running");}Pet t3 = new Pet(3); }public class OrderOfInitialization {public static void main(String[] args) {Person p = new Person();p.show();} }
【运行结果】:
Pet(1)
Pet(2)
Pet(3)
---Person()---
Pet(33)
show----running
上例中,虽然t1、t2、t3的定义遍布于类中,但是初始化的先后顺序是由t1、t2、t3的定义顺序决定的(自己动手调换t1、t2、t3看看结果),且初始化优先于构建器执行,当调用Person的构建器时,t3重新初始化。
静态数据的初始化
如果数据是静态的(static),同样的过程也会执行。若属于基本类型,而且未对其进行初始化,就会自动获得自己的标准基本类型初始值;若它是指向一个对象的句柄,除非创建一个对象同它连接起来,否则得到一个空值(null)。如果在定义时初始化,采取的方式与非静态值是不同的,这是因为static只有一个存储区域。例如:
class Bowl {Bowl(int marker) {System.out.println("Bowl(" + marker + ")");}void f(int marker) {System.out.println("f(" + marker + ")");} }class Table {static Bowl b1 = new Bowl(1);Table() {System.out.println("Table()");b2.f(1);}void f2(int marker) {System.out.println("f2(" + marker + ")");}static Bowl b2 = new Bowl(2); }class Cupboard {Bowl b3 = new Bowl(3);static Bowl b4 = new Bowl(4);Cupboard() {System.out.println("Cupboard()");b4.f(2);}void f3 (int marker) {System.out.println("f3(" + marker + ")");}static Bowl b5 = new Bowl(5); }public class StaticInitialization {public static void main(String[] args) {System.out.println("Creating new Cupboard() in main");new Cupboard();System.out.println("Creating new Cupboard() in main");new Cupboard();t2.f2(1);t3.f3(1);}static Table t2 = new Table();static Cupboard t3 = new Cupboard(); }
【运行结果】:
Bowl(1)
Bowl(2)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)
静态代码块
Java允许将其他static初始化工作划分到类内一个特殊的代码块中,这种代码块的形式为static关键字,后面跟着一个方法主体,称为静态代码块。静态代码块只有在第一次生成那个类的对象或首次访问属于那个类的static成员时执行。例如:
class Person {Person(int age) {System.out.println("Person(" + age + ")");}void f(int age) {System.out.println("f(" + age + ")");} }class Persons {static Person p1;static Person p2;static {p1 = new Person(1);p2 = new Person(2);}Persons() {System.out.println("Persons()");} }public class ExplicitStatic {public static void main(String[] args) {System.out.println("Inside main()");Persons.p1.f(18);//1 }static Persons x = new Persons();//2static Persons y = new Persons();//2 }
在标记为1的行内访问static对象p1的时候,或在行1被注释而行2未被注释是,用于Persons的static初始化模块就会运行。若1和2都被注释掉,则用于Persons的静态代码块不会执行。
静态属性和静态代码块执行的先后顺序
class Person {Person(int age) {System.out.println("Person("+age+")");} } class Persons {static Person p = new Person(2); // 1static {p = new Person(3);}static Person p = new Person(2); // 2 } public class CompStaticInit {public static void main(String[] args) {}static Persons x = new Persons(); }
根据注释1保留2,注释2保留1的结果分析可知,静态属性和静态代码块的执行顺序取决于编码的顺序。谁在前面就先执行谁。
非静态属性的初始化
class Animal {Animal(int age) {System.out.println("Animal(" + age + ")");}void f(int age) {System.out.println("f(" + age + ")");} } public class NotStaticInit {Animal a1;Animal a2;{a1 = new Animal(1);a2 = new Animal(2);System.out.println("a1 & a2 initialized");}NotStaticInit() {System.out.println("NotStaticInit");}public static void main(String[] args) {System.out.println("Inside main()");NotStaticInit x = new NotStaticInit();} }
类似于静态代码块,匿名代码块与非静态属性的初始化顺序取决于编码顺序。
继承中的对象初始化过程
class Insect {int i = 1;int j;Insect() {prt("i = " + i + ", j = " + j);j = 2;}static int x1 = prt("static Insect.x1 initialized");static int prt(String s) {System.out.println(s);return 3;} }public class Beetle extends Insect {int k = prt("Beeklt.k initialized");Beetle() {prt("k = " + k);prt("j = " + j);}static int x2 = prt("static Bootle.x2 initialized");static int prt(String s) {System.out.println(s);return 4;}public static void main(String[] args) {prt("Beetle constructor");Beetle b = new Beetle();} }
【运行结果】:
static Insect.x1 initialized
static Bootle.x2 initialized
Beetle constructor
i = 1, j = 0
Beeklt.k initialized
k = 4
j = 2
对Beetle运行Java时,发生的第一件事情是装载程序到外面找到那个类。在装载过程中,装载程序发现一个基础类,所以随之将其载入。无论是否生成基础类的对象,这一过程都将执行。如果基础类含有另一个基础类,则另一个基础类随即也会载入,以此类推。接下来就在根基础类中执行static初始化,再在下一个衍生类中执行,以此类推。这是因为衍生类的初始化可能要依赖于对基础类成员的初始化。
当类都装载完毕,就能创建对象。首先,这个对象中的所有基本数据类型都会设置成为他们的默认值,对象句柄设为null。然后执行基础类的构建器。这种情况是自动完成的(衍生类的构造函数中默认调用了super()
,也可以通过super指定基类的构建器)。基础类构建器完成后,衍生类实例变量就会按本来的顺序得到初始化,然后执行构建器的剩余的主体部分。
总结对象创建的过程:
- 静态只在类加载的时候执行且只执行一次;
- 非静态只有在实例化的时候执行,每次创建对象都执行;
- 静态在非静态之前执行,基类静态优先于衍生类静态执行;
- 静态属性和静态代码块的执行属性取决于它们在类中的位置,谁在前先执行谁;
- 非静态属性和构造块的执行顺序取决于它们在类中的位置,谁在前执行谁。
(002) java后台开发之对象初始化相关推荐
- 远景能源java后台开发实习面试题
远景能源java后台开发实习面试题 springboot MVC mysql优化(建索引) 锁,自旋锁,轻量锁 Java动态代理 垃圾回收 hashmap底层,怎么查数据,取余 string和stri ...
- (001) java后台开发之流程初识
java 后台开发流程 这篇文章为了奠基一下被我打入冷宫两个月左右的iOS开发,因为之前由于iOS项目停止的原因,被调至后台开发,两个月中也学习到了很多关于Java.sql.js.jsp的内容,感谢我 ...
- 长沙哪招jaVa后端开发人才_求职:Java后台开发-何柄融-湖南大学
联系方式 找到工作了,就不乱发了.谢谢. 个人信息 何柄融/男/1997 本科/湖南大学/自动化专业/19届 技术博客:何柄融www.zhihu.com 期望职位:java后台开发 项目经历 蔬菜大 ...
- 蘑菇街Java后台开发一二面面经
蘑菇街Java后台开发一二面面经 本菜鸡妹妹的春招上岸之路,第一次挂经献给蘑菇街. 时间线 时间 状态 2020/3/6 内推投递后端开发岗位 2020/3/11 邮件确认一面时间 2 ...
- 用IDEA进行Java后台开发(三)
在上一篇用IDEA进行Java后台开发(二)中我们已经可以成功的调用我们所写的接口,并且做了一些简单的逻辑处理, 由于后台开发离不开数据,所以这篇将进行Servlet于MySQL数据库链接和简单的调用 ...
- 跨专业转计算机拿下百度java后台开发的经验分享
前言 本文出自我的一位朋友,他是跨专业最终成功转行计算机,拿下了百度的java后台开发offer,之前他一直说着要给大家分享一波经验,今天完成了写作,希望对大家有帮助.(PS:另外也欢迎大家投稿分享自 ...
- 美团、滴滴实习生面经(滴滴offer,Java后台开发岗)
笔者是大三本科生,一直以来在考研和参加工作两个想法之间徘徊,最终在今年3月份下定决心参加工作,之后参加了春招,投的全部是java后台开发岗实习生. 在春招过程中投了不少公司,有京东.头条.网易.美团. ...
- 【Java后台】从零开始的Java后台开发(三)
编写基础的Servlet应用程序 1 Servlet 使用Servlet需要在pom.xml中引入以下依赖: <!-- https://mvnrepository.com/artifact/ja ...
- JAVA后台开发访问第三方接口(GET)
java后台开发访问第三方接口(GET) public static void main(String[] args) {// 创建Httpclient对象CloseableHttpClient ht ...
最新文章
- 巧用MySQL InnoDB引擎锁机制解决死锁问题
- python数据包的作用_使用Python将登录数据包发送到Minecraft服务器不起作用
- API 类和面向对象简介
- iOS:Masonry练习详解
- java 0 1背包_浅谈java实现背包算法(0-1背包问题)
- Qt文档阅读笔记-Custom Items Example解析
- C++二分查找,时间复杂度是O(logn)
- 数据结构上机实践第10周项目1 - 二叉树算法验证
- Windows Phone SDK 7.1 简体中文版离线安装包地址
- linux qt 触摸屏事件,利用触摸屏获取事件坐标
- linux 查看文件开头几行、末尾几行、中间几行
- ftl模板导出excel_ftl方式导出excel
- linux分析mirna,一篇15分的miRNA芯片文章详细解读 | 文章解读
- 在这个“未来工厂”里, 人类仅凭脑电波控制机器
- 做美食与互联网产品的关系
- android 播放器sdk,Android端SDK的使用
- 腾讯企业邮箱免费注册及登录方法
- 计算机教师访谈报告,计算机老师述职报告
- npm、cnpm、yarn安装指定版本的依赖包
- python selenium根据url获取cookie信息
热门文章
- Linux命令:MySQL系列之五--SELECT单表查询、多表查询升级及删除,插入
- Phalcon 訪问控制列表 ACL(Access Control Lists ACL)
- SQLServer执行命令出现“目录无效的提示”
- MWC2015中的LTE软基站(转自GeeFlex)
- 今天来说一下我的SAMC
- 快速撑握C#知识点系列文章
- MyBatis源码骨架分析
- Mac安装和启动memcached
- python 试题归纳及答疑 更新中.....
- React Native学习(七)—— FlatList实现横向滑动列表效果