Java匿名对象与构造器
Dog haQiShi = new Dog();
//打印对象:包名.类名@十六进制的hashCode
System.out.println(haQiShi);//面向过程.Dog@7852e922
匿名对象
创建一个对象,没有把它赋值给任何一个变量
匿名对象只是在堆中开辟一块新的内存空间,
但是没有把该空间地址赋值给任何变量.
因为没有名称,匿名对象仅仅只能使用一次,一般的,把匿名 对象作为方法的传参实现
对象的生命周期(从生到死的过程)
一个对象没有任何东西指向的时候,就会成为垃圾.
每次使用new关键字的时候,就会在内存中开辟新的空间,此时对象开始存在
对象的结束:当堆中的对象,没有被任何变量所引用,此时该对象就成了 垃圾,就等着垃圾回收器(GC)来回收该垃圾,当被回收的时候,对象被销毁了,回收垃圾的目的,释放更多的内存空间.
Dog haQiShi = new Dog();
Dog td = new Dog();
td=haQiShi;//把哈士奇的地址给了泰迪,然后在栈中就没有东西指向泰迪的地址,就会成为垃圾,会被回收
对象比较操作
==号:对于基本数据类型来说,比较的是值.
对于引用数据类型来说,比较的是在内存中的地址值
每次使用new关键字,都便是在堆中新开辟一块内存空间,不同的内存空间,地址值不同
用户会员练习
/*功能实现:
* 判断用户是否为会员 用户类(User)有两个状态: name(名字) isVip(是否成为会员) 有一个行为确定自己是不是会员
*/
package 面向对象;
public class User {//定义一个用户类
String name;//用户名字
boolean isVip = false;//初始值是否vip
void checkVip(boolean isVip) {//方法判断用户是否vip
if (isVip) {
System.out.println( ",恭喜你成为俊杰的vip");
} else {
System.out.println(",很遗憾你没能成为俊杰的vip");
}
}
public static void main(String[] args) {
//创建用户
User user1 = new User();
user1.name = "阿莹";
user1.isVip = true;
User user2 = new User();
user2.name = "允中";
user2.isVip = false;
// 把用户存起来
User[] allUser = new User[] { user1, user2 };
//从数组当中一个一个取出元素,判断每一个元素是不是会员
for (User user : allUser) {//foreach 遍历数组
System.out.print(user.name);
user.checkVip(user.isVip);
}
}
}
构造器
在创建对象时,自动调用的方法,我们称它是构造器
Test user1 = new Test(); new Test()就是一个构造器
在类中找不到默认的构造器,通过反编译工具可以看到默认的构造方法
编译器编译源文件时,会创建一个缺省的构造器,如果设置了默认值,默认值也是在构造器当中设置的
//状态: 成员变量 -> 字段
String name="谢霆锋";//字段的默认值,他是在默认的构造器中设置的
会在编译器中变成这样子
String name;
public Test()
{
name = "谢霆锋";
}
构造器的作用
1.创建对象,必须和new 一起使用
2.完成对象的初始化操作
构造器的特点
1.构造器的名称和当前类名一样的
2.禁止有返回类型,千万不能使用void作为返回值
3.在构造器当中不能使用retrun
构造器其实是有返回值的,它返回的是当前创建对象的地址
4.创建对象其实是在调用构造器
5.一个类至少存在一个构造器
默认构造器的特点
1.符合构造器的特点
2.没有参数
3.如果类使用了public修饰,它创建默认的构造器也会加public
自定义构造器
1.自己写的构造器,就被称为自定义构造器
2.自己写的构造器,要符合构造器的特点
3.自己定义了构造器,编译器就不会帮你再去生成构造器了
public class Test02(与class名一致)
Test02 test = new Test02("张三");//自定义构造器
自定义构造方法给成员变量初始化
在创建对象的时候,就要求设置好内部的状态值
构造器其实就是一个特殊的方法
String userName;
int userAge;
//在使用构造器时,必须对其里面的成员变量进行初始化
Test02(String name, int a) {
userName = name;
userAge = a;
}
static void hello() {
System.out.println("hello");
}
构造器的重载与方法重载一样
可以定义多个构造器,构造的方法名一样
参数不一样,在创建对象时,根据参数不同,调用不同的构造器
方法重载:方法名相同,参数不一样
构造器重载:方法名相同,参数不一样
static修饰符
状态和行为有:类和对象之分
如果你在字段和方法前添加了static,那么它的字段和方法就属于类
特点:
1.static修饰的内容,是随着类的加载而加载的
当JVM把字节码加载到虚拟机当中,static它试试的成员会自动加载到内存当中(方法区)
2.static修饰的内容,优先于对象的存在
3.static修饰的内容,被该类型的所有对象所共享
4.static修饰的内容可以直接使用类名来调用
package 面向对象;
public class Person {
// 人口
static int totalNums = 0;
// 毁灭
static void destroy() {
System.out.println("人类毁灭啦");
Person.totalNums=0;
}
// --------以上属于人类---------
String name;
int age;
void die() {
System.out.println(name + "死了");
Person.totalNums--;
}
// --------以上属于对象---------
// 构造器的作用,创建对象,一创建对象时,就给内部字段做初始化
Person(String n, int a) {
name = n;
age = a;
Person.totalNums++;
}
public static void main(String[] args) {
Person per = new Person("王popo", 99);
per.die();
Person per2 = new Person("李四", 2);
Person.destroy();
System.out.println(Person.totalNums);
}
}
static内存分析
类的成员
字段(成员变量)/方法/内部类
类成员与实例成员
类成员:使用static修饰的成员
实例(对象)成员:没有被static修饰的成员
类成员和实例成员的访问
在static方法中只能调用static成员
静态方法只能访问静态成员
非static方法,可以访问静态成员也可以访问非静态成员
可以通过对象来去调静态成员
本质还是通过类名来调用
什么时候使用static
被所有对象共享时,节省空间,没有必须每个对象都存储一份,可以直接使用类名调用
变量划分
变量: 数据类型 变量名 = 值
1.成员变量(全局变量,字段)
直接定义在类中的变量
1.类成员变量 在成员变量前加static,就是类成员变量
2.实例成员变量 没加static,就是实例成员变量
注意:在方法当中不能定义static变量,static变量属于类,方法属于对象
成员变量是有初始值的;不给初始值,会有默认,可以直接使用
2.局部变量
1.方法内部的变量.
2.方法的参数
3.代码块中的变量
定义在方法当中的变量(参数,和内部定义的变量,代码块)
局部变量的初始化:必须得要初始化之后才可以使用(在内存中开辟空间)
变量作用域
变量的作用域指的是变量的存在范围,只有在这个范围内,程序代码才能访问它.
当一个变量被定义时,它的作用域就确定了
变量根据定义的位置不同,也决定了各自的作用域是不同的.看变量所在的{}
变量的生命周期
变量的生命周期值得是一个变量被创建并分配内存空间开始,到该变量被销毁并清除其所占内存空间的过程.作用域不同,生命周期就不一样
成员变量:在整个类中都有效
局部变量:只在它定义的大括号中生效
成员变量,可以先使用后定义,局部变量必须先定义而后使用.
存放位置 | 生命周期开始 | 生命周期结束 | 内存位置 | |
---|---|---|---|---|
类变量 | 字段,使用static | 所在字节码加载到JVM时 | 当JVM停止时 | 方法区 |
实例变量 | 字段,没有static | 创建所在类对象时 | 当对象被GC回收时 | 堆 |
局部变量 | 方法参数,方法内,代码块 | 执行到初始变量时 | 所在的方法或代码块执行结束 | 栈 |
package包
可以平面展示,也可以树状展示
什么是包
在开发中,我们存在几百上千的Java文件,如果所有Java文件都存放在一个目录中,管理起来也很痛苦,Java也可以创建一个类似文件夹的东西,我们称这个文件夹为包
包的作用:
1.把功能相似或者相关的类或接口组织在同一个包中,方便类的查找和使用
2.如同文件夹一样,包采用了属性目录的存储方式.同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同的类时,应该加上包名加以区别.因此包可以避免名字冲突
3.包也可以限定访问权限,拥有包访问权限的类才能访问某个包中的类
包的语法
package 包名.子包名.子子包
必须把该语句作为Java文件中,并且是第一行代码
包名定义
1.包名必须要遵守标识符规范 全部小写
2.企业开发中,包名用公司 域名倒写.
使用格式:Package 域名倒写.模块名.组件名;
cn.webholiday.login
类的名称
类的简单名称:直接类名
类的全限定名称:包名.类名
在开发中,都是先有package然后在package中再定义类
包当中的import关键词
当A类和B类不在同一个包的时候,若A类需要使用到B类,此时就得让A类中去引B类
Ctrl+Shift+O eclipse快速导包
系统提前帮我们做了很多功能,它们都放进包里面了,我们只需要把它们从指定的包里面导入,就可以使用了
使用系统提供的功能,需要从系统的包里面导入类
静态导入(了解,不要使用)
把其他包里的内容在本类当中直接使用
不需要使用类名调用,直接使用别的包里的方法
静态导入用法: import static类的全限定名,该类中的static成员名;
在实际开发中,我们不使用静态导入,因为如此,分不清某一个静态方法或字段来源于哪一个类.