栈存取速度快的原因是:
如果我们在堆内存中new了一个对象出来,但是在栈内存中并没有声明其引用,此时我们称之为匿名对象
由于匿名对象使用后马上被GC了,因此只会存在一次,一般工具类我们会用这种形式
如果一个对象,想使用2次或以上,一定要创建对象名。
如果在某一个构造函数A中,通过this调用另外一个构造函数B,则必须把B写在A方法的第一行,否则会报错(原因:如果在B前面写了其他代码,此时整个对象并没有构造完毕)。
static修饰的属性和方法,伴随着class的生成而加载,与具体的对象无关,在class加载时就会在方法区中生成初始化。
无论class下面new了多少个对象,static修饰的属性,内存中只保存了一份。
在访问时候,静态资源不能访问非静态,非静态的资源或方法可以访问静态的!(由于静态生成的较早,不依赖于具体的对象)
修饰符 | 类 | 包 | 子类 | 其他包 |
---|---|---|---|---|
public | y | y | y | y |
protected | y | y | y | n |
default | y | y | n | n |
private | y | n | n | n |
使用extend进行继承
java中只有单继承、多重继承(A继承B,B继承C),没有多继承(没有A继承B,同时A继承C)
子类实例化的时候,会自动new一个父类的对象,该父类对象完全生成后,才进行子类对象的生成
在子类对象生成过程中,自动添加一个super属性,该属性指向其父类对象的内存地址
在代码中,调用子类对象的属性和方法时,会首先看该子类对象本身特有的,如果子类对象存在这个属性/方法,则直接调用(方法的重写),否则会去调用.super.属性/方法
+ 子类实例化时,自动创建的父类对象,此时调用的是父类的无参构造方法。如果将对应的父类的无参构造取消,此时子类的extend继承时,会报错。如果需要在继承时候,子类构造需要调用父类的指定某个构造,则可以在子类构造方法中,使用super(),调用父类指定的构造。
在某个类的构造中,this.()调用构造方法和super()调用构造方法都需要写在第一行,但是不能同时出现,因为同时出现不符合逻辑。
在子类代码中,super就表示被自动创建的父类对象。
public static final
接口可以多实现:
格式:
class 子类 implements 父接口1,父接口2…{
}
接口因为彼此都是抽象部分,不存在具体的实现,因此允许多继承,例如:
interface C extends A,B{
}
class 子类 extends 父类 implements 父接口1,父接口2...{
}
核心是定义(规范、约束)与实现的分离
优点:
Person p=null;
Student s=new Student();
Teacher t=new Teacher();
p=s;//父类引用,指向子类对象
p.say();
p=t;//父类引用,指向子类对象
p.say();
即一个p,可以有学生student这种形态,也可以有teacher这种形态。
Person p1=null;
Student s=new Student();
Teacher t=new Teacher();
p1=s;//向上转型
p1.say();
p2=t;//向上转型
Student s2=(Student) p1;//向下转型,需要强制转换;
Student s3=(Student) p2;//向下转型,需要强制转换,但是p2本质上不是一个Student,此时代码会报错
//定义下列方法实现
public static void say(Person p){
System.out.println("我是:"+p.name);
}
//用户可以进行不同实现的调用
public static void main(){
Student s=new Student();
say(s);
Nurse n=new Nurse();
say(n);
}
可以通过重写equals方法,定制每个类的对比方法,比如我们判断用户是否是同一个,在equals里面判断其身份证号或者手机号
public boolean equals(Object o){
if(this == o){
return ture;
}
if(o==null){
return false;
}
if(o instanceof Person){
Person p2=(Person) o;
if(this.name.equals(p2.name)&&(this.mobile ==p2.mobile)){
return ture;
}else{
return false;
}
}else{
return false;
}
}
/*
* 测试成员内部类
*/
public class Outer {
private int x=999;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
class Inner{
private int x=888;
public void say() {
System.out.println(x);//输出999
System.out.println(Outer.this.x);//输出888
}
}
}
/*
* 测试类
*/
public class Test {
public static void main(String[] args) {
Outer o=new Outer();
//用这个方法,声明成员内部类,同时new一个成员内部类
Outer.Inner i=o.new Inner();
i.say();//输出888,999
}
}
public class Demo1{
public static void main(String[] args){
//定义局部内部类
class Person{
public void say(){
System.out.Println("这是Person类,局部内部类");
}
}
//使用局部内部类
Person p=new Person(){
p.say();
}
}
}
public interface Person {
public void say();
public void drink();
}
public class Test {
public static void main(String[] args)
//调用匿名内部类
Person pe=new Person() {
public void say() {
System.out.println("这是匿名内部类实现1");
}
public void drink() {
// TODO Auto-generated method stub
System.out.println("这是匿名内部类实现2");
}
};
haha(pe)
}
//写了一个方法,传入的需要是接口的实现
public static void haha(Person p) {
p.drink();//返回:这是匿名内部类实现2
}
}
public class Test {
public static void main(String[] args)
int aa=100;
//调用匿名内部类
Person pe=new Person() {
public void say() {
System.out.println("这是匿名内部类实现1"+aa);
}
public void drink() {
// TODO Auto-generated method stub
System.out.println("这是匿名内部类实现2"+aa);
}
};
haha(pe);//这是匿名内部类实现2
class PersonImp implements Person {
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("这是匿名内部类实现1-1"+aa);
}
@Override
public void drink() {
// TODO Auto-generated method stub
System.out.println("这是匿名内部类实现2-2");
}
}
PersonImp pi=new PersonImp();
haha(pi);//这是匿名内部类实现2-2
//aa=9;//如果此行不注释,上述代码会无法编译,
//因为在java编译的时候,会把所有的class编译成一个单独的class文件,此时由于内部类内部使用了这个内部类外部定义的变量,
//因此jvm会将这个变量copy一份,保存下来,放到这个文件中。因此系统从规则上限制了这个变量不可更改。
//所以内部类使用的局部变量,jvm会将这个变量,默认前面加上final。(只不过代码中省略了。。。)
//注释掉后,就美问题了!
}
//写了一个方法,传入的需要是接口的实现
public static void haha(Person p) {
p.drink();//返回:这是匿名内部类实现2
}
}
/*
* 测试类
*/
public class Test {
public static void main(String[] args) {
Outer.InnerStatic os=new Outer.InnerStatic();
os.say();
}
/*
* 测试静态内部类
*/
public class Outer {
private int x=999;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
static class InnerStatic{
private int x=123;
public void say() {
System.out.println("这是静态内部类内部");
}
}
}
序号 | 基本数据类型 | 包装类 |
---|---|---|
1 | int | Integer |
2 | char | Character |
3 | float | Float |
4 | double | Double |
5 | boolean | Boolean |
6 | byte | Byte |
7 | short | Short |
8 | long | Long |
/*
* 可变参数测试
*/
public class KebianParam {
public static void main(String[] args) {
// TODO Auto-generated method stub
sum("haha",20,12,13);
}
/*
* int... nums:表示可以传入0-n个int
* 在方法内部,可变参数可以用数组作为载体
*/
public static void sum(String s,int... nums) {
int res=0;
for(int i=0;i<nums.length;i++) {
res+=nums[i];
}
System.out.print(s+res);
}
}