一、类的定义
每一个源文件必须有且只有一个public class,且类名和文件名保持一致
一个Java文件可以同时定义多个class
public class Test{ //Test类名与文件名保持一致
public static void main(String[] args) {
}
public int Test3(){
}
class Test2{
}
}
class Test1{
}
二、 典型类的定义
难点
1、Computer comp; 定义一个类里面的对象,表示每人有一台电脑
2、Computer co1 = new Computer(); 在Computer类中创建一个对象
3、St.comp = co1; 将建好的对象给St的comp属性
4、comp.brand; comp是定义的对象,通过 . 访问里面的属性
//模拟学生使用电脑学习
public class Student {
int age;
String name = "hua";
int id;
Computer comp;
void play() {
System.out.println(name+"在打游戏,电脑牌子是"+comp.brand);//comp是对象但是没访问里面的brand属性
}
public static void main(String[] args) {
Student St = new Student();
Computer co1 = new Computer();
co1.brand = "联想";
St.comp = co1;
St.play();
}
}
class Computer{
String brand;
}
三、构造方法
1. 通过new关键字调用
2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值
3. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加。super()可以省略,是调用父类无参数的构造方法
4. 构造器的方法名必须和类名一致
案例:计算两点间的距离
class Point{
double x,y;
public Point(double _x,double _y) { //构造器
x = _x;
y = _y;
}
public double Getlength(Point j) {
return Math.sqrt((x - j.x) * (x - j.x) + (y - j.y) * (y - j.y));
}
}
public class Test{
public static void main(String[] args) {
Point p = new Point(3.0,4.0);
Point origin = new Point(0.0,0.0);
System.out.println(p.Getlength(origin));
}
}
难点:
1、用_x和_y是为了区分两点位置
2、Point p = new Point(3.0,4.0); 创建一个p对象将3.0和4.0赋值给x,y
3、Point origin = new Point(0.0,0.0); 创建一个origin对象将0.0和0.0赋值给origin对象里面的x和y(注意不用把p对象和origin混在一起,p的x和y值和origin的x和y值是不一样的)
4、p.Getlength(origin); 调用p对象里面的Getlength函数,origin作为参数,即里面的j.x和j.y就是origin的_x和_y
四、垃圾回收机制
1、新创建的对象,绝大多数都会存储在Eden中,
2、当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收(GC),将无用对象清理掉, 然后剩余对象复制到某个Survivor中,如S1,同时清空Eden区
3、当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2,同时将Eden区中的不能清空的对象,也复制到S1中,保证Eden和S1,均被清空。
4、重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中,
5、当Old区满了,则会触发一个一次完整地垃圾回收(FullGC),之前新生代的垃圾回收称为(minorGC)
Full GC: 用于清理年轻代、年老代区域。 成本较高,会对系统性能产生影响。
会被调用的原因1.年老代(Tenured)被写满 2.持久代(Perm)被写满
System.gc()写这个编码是程序建议GC启动,不是调用GC
五、this关键字
1、this关键字不能在static方法中使用
2、this关键字调用重载的构造方法需要放在第一行
3、不加this的局部变量是以就近原则,有this可以区分开局部变量和成员变量
4、this可以调用同一个类中的其他方法
public class This {
int a;
int b;
This(){
this(5); //this必须位于第一行
System.out.println("haha");
}
This(int a){
System.out.println("fafa"+a);
}
void play(int a,int b) {
this.a = 1;
System.out.println(a);
this.b = 1;
System.out.println(b);
this.sing(); //this可以调用同一个类中的其他方法
}
void sing(){
System.out.println(a); //a打印的是成员变量 a为1
}
public static void main(String[] args) {
This Th = new This(); //重载的构造方法,通过new直接调用
Th.play(2, 4);
//this.sing() 错误 不能在static使用
}
}
六、static关键字
1、对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享
2、在static方法中不可直接访问非static的成员,即不能调用非静态
public class This {
int a = 0;
int b;
void sing(){
swim(); //可以调用静态static方法
System.out.println(a);
}
static void swim(){
//sing(); 不能调用非static方法
swim1();
System.out.println("a");
}
static void swim1(){
System.out.println("c");
}
public static void main(String[] args) {
This Th = new This();
Th.sing();
}
}
七、参数传值机制
public class This {
int id; //id
String name; //账户名
String pwd; //密码
public This(int id, String name) {
this.id = id;
this.name = name;
}
public void testParameterTransfer01(This u){ //传的是u1地址
u.name="高小八"; //改了u1的name
System.out.println(u); //更改后仍然为一开始的u1地址
}
public void testParameterTransfer02(This u){ //传的u1地址
System.out.println(u); // 也是一开始的u1地址
u = new This(200,"高三"); //重新实例化u这个对象
System.out.println(u); //u为新的对象的地址,与u1不一致
}
public static void main(String[] args) {
This u1 = new This(100, "高小七");
u1.testParameterTransfer01(u1);
System.out.println(u1.name);
System.out.println(u1); //地址仍为刚开始的u1地址
u1.testParameterTransfer02(u1);
System.out.println(u1.name); //u1对象对应的name
}
}
八、包package
1、非注释语句第一行
2、在src中创建一个package 可以通过.的方式在window中放在多层文件夹中。
//两者不具有包含关系
package sn.aa 在sn文件夹里面的aa文件夹里面
package sn.aa.c 在sn文件夹里面的aa文件夹里面的c文件夹里面
九、import导入类
1、同一个包中的类调用可以直接new
(命名不规范)
//uu.java
package sn.a;
public class uu {
public static void main(String[] args) {
uu u = new uu();
u.Type();
}
public void Type(){
System.out.println("ty");
}
}
//cc.java
package sn.a;
public class cc {
public static void main(String[] args) {
uu u1 = new uu(); //不用import,直接new来导入uu包
u1.Type();
}
}
2、不同的包的类需要import里面的类使用
//uu.java 同上面代码一致
//cc.java
package sn.a;
import This.uu; //通过导入This包内的uu类
public class cc {
public static void main(String[] args) {
uu u1 = new uu();
u1.Type();
}
}
补充:cc.java 可能要调用uu.java和This1.java,可以通过*来导入包里面的所有类
如果只需导入一个类,一般不*来全部导入,会影响编译速度但不降低运行速度
import This.*
3、如果导入两个同名的类,只能用包名+类名来显示调用相关类
import java.util.Data;
import java.sql.Data;
public class cc {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
java.sql.Data date = new java.sql.Data();
}
}
4、静态导入(static import)
import static java.lang.Math.*;
public class cc {
public static void main(String[] args) {
System.out.println(Math.PI);
System.out.println(random()); //import加上static实现静态导入
}
}