package Practice;
class Cylinder {
/**
* 被static修饰的成员称为类成员,未被static修饰的称为实例成员
* 被static修饰的变量称为“静态变量”(类成员),被static修饰的方法称为“静态方法”(类方法)
* 使用格式:
* 类名.静态变量名;(建议使用)
* 对象名.静态变量名;
*/
private static int num = 0;
private static double pi = 3.14;
private double radius;
private int height;
// 无参构造方法
public Cylinder() {}
// 带参数的构造方法
public Cylinder(double radius, int height) {
this.radius = radius;
this.height = height;
num++;
}
// 一个构造方法调用另外一个构造方法时,必须使用this关键字,必须放在第一行
public Cylinder(double radius, int height, double PI) {
this(radius, height);
this.pi = PI;
}
/**
* 静态初始化器:将属性或方法变成全局,不用实例化,可直接调用。
* static{}:先构造方法被调用。
* 它的作用和构造方法有些类似,都是用来初始化工作的。
* 静态初始化器与构造方法的区别:
* 1.构造方法是对每个新创建的对象初始化,而静态初始化器
* 是对整个类自身进行初始化,包括static成员变量赋初值。
* 2.构造方法是在用new创建新的对象时由系统自动执行,
* 而静态初始化器一般不能由程序来调用,他是在所属的类
* 被加载入内存时由系统调用执行。
* 3.用new创建了多少个对象,构造方法就被调用多少次,
* 但静态初始化器则在类被加载入内存时只执行一次。
* 4.静态初始化器不是方法,它没有方法名、返回值和参数。
* 5.如果有多个静态初始化器,则它们在类的初始化时会依次执行。
*/
static {
num++;
}
// 静态方法测试
public void count() {
System.out.println(num);
}
public static void count1() {
System.out.println(num);
}
public double setCylider(double radius, int height) {
this.radius = radius;
this.height = height;
return radius+height;
}
// 重载: 方法名相同,参数列表不同(个数,类型,顺序),返回值和访问控制符可以相同,也可以不同
public double setCylider(int height, double radius) {
this.radius = radius;
this.height = height;
return radius+height;
}
double area() {
return pi* radius* radius;
}
double volume() {
return area()* height;
}
}
class Person{
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person compare(Person person) {
if(this.age > person.age)
return this;
else
return person;
}
public void show() {
System.out.println("name:" + name +"\n"+"age:" + age);
}
public static int minAge(Person [] p) {
int min = Integer.MAX_VALUE;
for(int i = 0; i < p.length; i++)
if(p[i].age < min)
min = p[i].age;
return min;
}
}
/**
* @author Administrator
* 垃圾回收(Garbage-collection)是Java提供的一种自动内存回收功能,
* 可以让程序员减轻许多内存管理的负担,也减少程序员犯错的机会。
* 当一个对象被创建时,JVM为该对象分配一定的内存、调用该对象的构造方法,并开始跟踪对象。
* 当对象停止使用时,JVM将通过垃圾回收器回收该对象所占用的内存。
*垃圾回收的好处:
* 它把程序员从复杂的内存追踪、检测和释放等工作解放出来;
* 它防止了系统内存被非法释放,从而使系统更稳定。
*垃圾回收的特点:
* 只有当一个对象不被任何引用类型的变量使用时,它的内存才可能被垃圾回收器所回收。
* 不能通过程序强迫回收器立即执行。
* 当垃圾回收器将要释放无用对象的内存时,先调用对象的finalze()方法。
*/
class LocalVarGC {
/**
* 在申请空间后,立即进行垃圾回收,很明显,由于byte数组被变量a引用,因此无法回收这块空间
*/
public void localvarGc1() {
byte[] a = new byte[6 * 1024 * 1024];
System.gc();
}
/**
* 垃圾回收前,先将a变量置为null,使byte数组失去强引用,故垃圾回收可以顺利回收byte数组
*/
public void localvarGc2() {
byte[] a = new byte[6 * 1024 * 1024];
a = null;
System.gc();
}
/**
* 进行垃圾回收前,先使局部变量a失效,虽然变量a已经离开了作用域,但是变量a依然存在于局部变量中,并且也指向这块byte数组,故byte数组依然无法被回收
*/
public void localvarGc3() {
{
byte[] a = new byte[6 * 1024 * 1024];
}
System.gc();
}
/**
* 垃圾回收之前,不仅使变量a失效,更是申明了变量c,使变量c复用了变量a的字,由于变量a此时被撤销,故垃圾回收器可以顺利回收byte数组
*/
public void localvarGc4() {
{
byte[] a = new byte[6 * 1024 * 1024];
}
int c = 10;
System.gc();
}
/**
* 首先调用了localvarGc1(),很明显,在localvarGc1()中并没有释放byte数组,
* 但是localvarGc1()返回后,它的栈帧被销毁,自然也包括了栈帧中的所有局部变量
* 故byte数组失去引用,在localvarGc5()的垃圾回收中被回收
*/
public void localvarGc5() {
localvarGc1();
System.gc();
}
public static void main(String[] args) {
// 初始化LocalVarGC类,并为每一个localvarGcN()函数分配一个6MB的堆空间,并使用局部变量引用这块空间
LocalVarGC ins = new LocalVarGC();
ins.localvarGc1();
}
}
public class ChapterSeven {
public static void main(String[] args) {
// 使用类名调用
Cylinder.count1();
Cylinder cylinder1 = new Cylinder();
// 使用对象名调用
cylinder1.count();
cylinder1.setCylider(3.2, 5);
System.out.println(cylinder1.area());
System.out.println(cylinder1.volume());
Cylinder cylinder2 = new Cylinder(2.5,3);
cylinder2.count();
System.out.println(cylinder2.area());
System.out.println(cylinder2.volume());
Cylinder cylinder3 = new Cylinder(2.5,3);
cylinder3.count();
// 对象的应用
Person person1 = new Person("张三", 20);
Person person2 = new Person("里斯", 30);
// 将person3的地址指向person1和person2中比较大的一个
Person person3 = person1.compare(person2);
if(person3 == person1)
System.out.println("张三的年龄大.");
else
System.out.println("里斯的年龄大.");
/**
* 类类型的数组:
* 用数组来存放对象一般需经历两个步骤:
* 1.声明类类型的数组变量,并用new运算符分配内存空间给数组。
* 2.用new创建新的对象,分配内存空间给它,并让数组元素指向它。
*/
Person [] per1 = new Person[3];
per1[0] = new Person("white", 10);
per1[1] = new Person("blue", 11);
per1[2] = new Person("yellow", 12);
per1[0].show();
per1[1].show();
/**
* 以对象数组为参数进行方法调用
* 传递数组时实参只需给出其数组名即可。
*/
Person [] per2 = new Person[3];
per2[0] = new Person("white", 10);
per2[1] = new Person("blue", 11);
per2[2] = new Person("yellow", 12);
System.out.println("最小的年龄为:" + Person.minAge(per2));
}
}