java 初始化
初始化
这里的主要内容是
初始化
相关的内容,其中还会穿插其他的内容
- 构造器初始化
- 静态数据初始化
- 显示的静态初始化
- 非静态实例初始化
穿插内容
- 构造器
- 方法重载
- this关键字
- static 关键字
构造器初始化
构造器
构造器是在创建对象时被调用的特殊方法。(构造器是一个方法只不过它是特殊的),之所以特殊是因为构造器没有返回值。与返回空(void)不同。一个简单的说法,普通方法就算是void,还是可以掉的,但构造器没得改。构造器是一个静态的方法,
构造器中的方法名与它所在的类名相同。这是因为为了让编译器能够知道该调用那个方法。在创建对象时,编译器将为对象分配存储空间,并调用相应的构造器,这保证了你在操作对象之前,恰当的初始化了。
public class Apple {
// 默认构造器
Apple(){
System.out.println("Hello Word");
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple();
}
}
没有参数出入的构造器叫默认构造器,术语是无参构造器,有参数的叫有参构造器。
public class Apple {
//有参构造器
Apple(String a){
System.out.println(a);
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple("Hello Word");
}
}
如果 Apple(String)
是类里唯一一个构造器,那么你在创建对象时必须传入参数。
注意:在java中初始与创建是捆绑在一起的,二者不能分离
默认构造器在没有其它的构造器时,编译器会自动创建一个默认构造器,如果类中有了构造器(无论是否有参数),编译器就不会自动创建了。如果没有构造器,就无法创建对象。
像下边这么写就会编译器会报错,因为 编译器没有找到 new Apple();
没有参数的构造器
public class Apple {
Apple(String a){
System.out.println(a);
}
public void t(){
return;
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple();
}
}
像下边加一个无参构造器即可。
public class Apple {
Apple(){
System.out.println("Hello Word");
}
Apple(String a){
System.out.println(a);
}
public void t(){
return;
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple();
}
}
在上边的 Apple
类中,两个构造器它们名字相同,传入的参数不同,这种写法叫 方法重载
,在普通方法中也同样适用
方法重载
方法重载就好比相同的词可以表达不同的含义,重载方法名字要相同其中一个重要原因是因为构造器,的名字要与类名相同,这样只有一个构造器名,就可用多种方式创建一个对象。普通方法的重载也和构造器一样。
public class Apple {
/* 重载构造器 */
Apple(){
}
Apple(String name){
}
Apple(String name, Integer num){
}
Apple(Integer num, String name){
}
/* 重载的方法 */
/**
* 获取苹果
*/
public void getApple(){
}
/**
* 获取特定品种的苹果
* @param type 品种
*/
public void getApple(String type){
}
/**
* 获取特定品种,即某一数量的苹果
* @param type 苹果品种
* @param num 苹果数量
*/
public void getApple(String type, Integer num){
}
/**
* 获取特定品种,即某一数量的苹果
* @param num 苹果品种
* @param type 苹果数量
*/
public void getApple(Integer num, String type){
}
}
java区分方法名相同的方法,是根据每个方法的独一无二的参数列表去区分的。
如下这种情况虽然java允许 ,也最好不要用,因为会使得程序难以维护
Apple(String name, Integer num){
}
Apple(Integer num, String name){
}
/**
* 获取特定品种,即某一数量的苹果
* @param type 苹果品种
* @param num 苹果数量
*/
public void getApple(String type, Integer num){
}
/**
* 获取特定品种,即某一数量的苹果
* @param num 苹果品种
* @param type 苹果数量
*/
public void getApple(Integer num, String type){
}
拓展:java为什么不用返回区重载方法。
有的时候并不需要一个方法返回东西,只需要方法本身的作用。
public void test(){
a();
}
public void test(String name){
b(name);
}
this 关键字
this关键字只能在方法内部使用,表示“调用方法的那个对象”。比如在Apple类的后一个方法中使用了this,this代表的就是Apple类。
public class Apple {
public void getApple(){
}
public void juice(){
this.getApple();
}
}
注意:在上边的 juice() 方法中有调用,同一个类中的方法 getApple() ,在这里是没有必要加 this的,因为编译器会自动帮忙加上。虽然手动加也可以,不过高级语言之所以高级,其中一个原因就是它可以帮助我们省略一些重复的事情。
只用当需要指明当前对象时才需要使用 this
public class AppleNum {
private int appleNum = 0;
public AppleNum sumAppleNum(){
appleNum ++;
return this;
}
public void print(){
System.out.println("总和:" + appleNum);
}
public static void main(String[] args) {
AppleNum appleNum = new AppleNum();
appleNum.sumAppleNum().sumAppleNum().sumAppleNum().print();
}
}
如上代码 sumAppleNum() 方法返回的 appleNum 对象的引用,从而使得可以循环调用 sumAppleNum() 方法。
this 可以有参数列表用于构造器调用构造器,构造器不能使用方法名调用构造器,也不能在普通方法普通方法中。在同一个构造其中 this只能调用一个构造器。
AppleNum(){
this("a");
}
AppleNum(String type){
this(3);
}
AppleNum(Integer i){
}
public AppleNum sumAppleNum(){
// this(3) 编译器会报错
}
成员初始化
如果类中的基本类型字段没有初始化,那java会为他们赋上默认值
public class Apple {
boolean t ;
char c;
byte b;
short s;
int i;
long l;
float f;
double d;
Apple apple;
public void get(){
System.out.println(t);
System.out.println(c);
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(apple);
}
public static void main(String[] args) {
Apple apple = new Apple();
apple.get();
}
}
从上边代码可以看出,基本类型变量没赋值,java会默认赋上初始值。对象赋上 null
,初始化的顺序,影响着程序的正确性。
静态数据初始化
除非用 new 创建对象,否则实际上并未获得任何对象。如果不想创建对象也能调用某一方法或属性,就可以使用static 关键字。当声明一个事物是 static
时,就意味着这个域或方法不会它所在的类的对象实例关联在一起。
static关键字
加上了 static
关键字,即为静态成员变量。
public class Apple {
static int i = 1;
public static void get(){
}
public static void main(String[] args) {
Apple.get();
int num = Apple.i;
}
}
上边展示了 static 关键字的基本用法,不用 new 对象也可以调用方法,虽然不用创建对象也可以调用方法,并不是说每个方法都加上 static
, 如果你的代码是这样,那你就得考虑一些你代码的设计问题了。
下边是加了 static
,与没加 static
的区别
public class Apple {
static int i = 1;
int b = 2;
public void get() {
System.out.println(i);
System.out.println(b);
}
public void set(int b){
// 这里因为入参的名字,与字段名相同 一般使用 this 将其区分
this.b = b;
}
public static void main(String[] args) {
Apple a = new Apple();
Apple b = new Apple();
a.get();
b.get();
/*====*/
System.out.println(" /*====*/ ");
Apple.i = 10;
b.set(3);
a.set(4);
a.get();
b.get();
}
}
通过上边的输出返现 , a b 两个对象在输出 i 时是相同的,a.i b.i指向了同一个内存地址。这也说明多了无论创建多少对象,静态数据都只占一份存储区域。
静态初始化只有在必要时刻才会进行,例如,如果创建 Apple 对象 或者 不调用 Apple.i 那静态的 i 永远不会被创建出来。
显示的静态初始化
多个静态初始化,可以简化成一个静态块
public class Apple {
static {
int i;
char a;
Apple c= new Apple()
}
}
上边这么写,因为是在大括号里,意味着是局部变量除非将对象返回出去,否则外边的方法,里边的属性
public class Apple {
Apple c;
static {
c = new Apple();
}
}
非静态实例初始化
非静态实例初始化,看起来和静态块非常像,区别就是没有 static
关键字
public class Apple {
Apple c;
{
int i;
char a;
c = new Apple();
}
}
这个写法的非静态初始化主要是为了匿名内部类准备的。这保证了不管调用那个构造器这部分代码都会被自行
public class Apple {
Apple(){
System.out.println("5");
}
{
System.out.println("2");
}
static {
System.out.println("1");
}
{
System.out.println("4");
}
{
System.out.println("3");
}
public static void main(String[] args) {
Apple apple = new Apple();
}
}
从上边的代码运行输出可以看出,静态块先被执行,然后是非静态块,最后是,构造器