1、带参数方法定义
格式:public static void 方法名(参数){......}
格式(单个参数):public static void 方法名 (数据类型 变量名){......}
public static void isEvenNumber (int number) {......}
2、接口的特点
1)接口用关键字interface修饰 public interface接口名{}
2)类实现接口用implements表示 public class 类名 implements 接口名{}
3)接口不能实例化
接口如何实现实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态。
多态的形式:具体类多态,抽象类多态,接口多态。
多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现) 类对象
4)接口的实现类
要么重写接口中的所有抽象方法
要么是抽象类
5)接口里的成员变量只能是常量,且被静态修饰,(一般默认有static final修饰),接口里没有非抽象方法(一般默认有public abstract修饰),接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在的。
6)一个类如果没有父类,默认继承自Object类
7)接口使用成员方法时,不能有方法体:Interface abstract methods cannot have body
3、类和接口的关系
1)类和类的关系
继承关系,只能单继承,但是可以多层继承
2)类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
3)接口和接口的关系
继承关系,可以单继承,也可以多继承
4、String line = sc.nextLine();用于获取键盘录入字符串数据
5、String构造方法
public String():创建一个空白字符串对象,不含有任何内容
public String(char[] chs):根据字符数组的内容,来创建字符串对象
public String(byte[] bys):根据字节数组内容,来创建字符串对象
String s=”abc”;直接赋值的方式创建字符串对象,内容就是abc(推荐使用)
6、Set集合特点
1)set集合不包含重复元素的集合
2)没有带索引的方法,所以不能用普通for循环变量
3)Hashset:对集合的迭代顺序不做任何保证
7、Map集合的遍历(方式一)
1)获取所有键的集合,用keySet()方法实现
2)遍历键的集合,获取到每一个键,用增强for循环实现
3)根据键去找值,用get(Object key)方法实现
8、内部类的访问特点
1)内部类可以直接访问外部类的成员,包括私有
2)外部类要访问内部类的成员,必须要创建对象
9、Math类没有构造方法,想要使用类中的成员,看类的成员是否都是静态的,如果是,通过类名就可以直接调用
10、Thread类中设置和获取线程优先级的方法
1)public final int getPriority():返回此线程的优先级
2)public final void getPriority(int newPriority):更改此线程的优先级
线程默认的优先级是5;线程优先级的范围是1-10;
线程优先级高仅仅表示线程获取得CPU时间片的几率高,但是要在次数比较 多,或者多次运行的时候才能看到你想要的效果。
11、相比继承Thread类,实现Runnable接口的好处
1)避免Java单继承的局限性
2)适合多个相同程序代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好地体现了面向对象的设计思想。
12、同步代码块
锁多条语句操作共享数据,可以使用同步代码块实现
1)格式:synchronized(任意对象){
多条语句操作共享数据的代码
}
2)synchronized(任意对象):就相当给代码加锁了,任意对象就可以看成一把锁。
同步的好处和弊端
3)好处:解决了多线程的数据安全问题
4)弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形之中会降低程序运行效率。
13、网络编程的三要素
1)IP地址:唯一标识网络中的设备
2)端口号:唯一标识设备中的应用程序
3)协议:通信双方必须同时遵循对应的协议才能完成数据交换,常见的协议有UDP协议、TCP协议
14、UDP发送数据
1)创建发送端的Socket对象(DatagramSocket)
2)创建数据,并把数据打包
3)调用DatagramSocket对象方法发送数据
4)关闭发送端
15、UDP接收数据
1)创建接收端的Socket对象(DatagramSocket)
2)创建一个数据包,用于接收数据
3)调用DatagramSocket对象方法接收数据
4)解析数据包,并把数据在控制台显示
5)关闭接收端
17、不能创建对象的三种情况
1)第一种:private修饰的私有对象
构造方法私有,不能创建对象
原因 :因为子类要创建对象,继承父类。就得调用父类的构造方法,此时父类的构造方法被私有了,也就不能创建对象了。
2)第二种:抽象类
原因 :抽象类(父类)里的方法很有可能是抽象方法。假如抽象类也能创建对象,创建对象之后,它调用自己的方法,而此时的方法却没有方法体,这时候创建的对象也没有意义,所以说抽象类不能创建对象。
拿animal的例子来想,动物是一个抽象类,抽象类不是具体的事物,如果创建一个动物的对象,那它有可能是猫,也有可能是狗,那就不确定了。
3)第三种:接口
原因 :接口创建不了对象,因为成员变量默认都是常量。而构造方法是用来给成员变量初始化并赋值的,此时成员变量是常量,所以无意义。故接口没有构造方法,也创建不了对象。
16、TCP发送数据的步骤
1)创建客户端的Socket对象(Socket)
2)获取输出流,写数据
3)释放资源
17、TCP接收数据的步骤
1)创建服务器端的Socket对象(ServerSocket)
2)监听客户端连接,返回一个Socket对象
3)获取输入流,读数据,并把数据显示在控制台
4)释放资源
18、网络编程出现的问题
客户端:数据来自于文本文件,接收服务器反馈
服务器:接收到的数据写入文本文件,给出反馈
出现问题:程序一直等待
原因:读取数据的方法是阻塞式的
解决方法:自定义结束标记;使用shutdownOutput()方法(推荐)
19、泛型的好处
1)把运行时期的问题提前到了编译期间
2)避免了强制类型转换
20、成员变量:类中方法外的变量,局部变量:方法中的变量
21、static关键字在使用的时候需要注意的几点
1)在静态方法中不可以使用this关键字
2)在静态方法中不可以直接调用非静态方法
3)局部变量不可以使用static关键字声明
4)主方法必须使用static声明
5)只有内部类才可以使用static关键字声明
22、final关键字
1)修饰方法:声明该方法是最终方法,不能被重写
2)修饰变量:表明该变量是常量,不能被再次赋值
3)修饰类:表明该类是最终类,不能被继承
4)变量是基本类型:final修饰的是基本类型的数据值不能发生改变
5)变量是引用类型:final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
23、抽象类和接口的区别
抽象类是对事物的抽象(包括行为和属性),而接口是对行为的抽象。
门和警报的例子
门:都有open()和close()两个动作,这个时候,我们可以分别使用抽象类和接口来定义这个抽象概念
//抽象类
public abstract class door{
public abstract void open();
public abstract void close();
public abstract void alarm();
}
所有继承了这个抽象类的子类都具备了报警功能,有的门根本不需要报警功能
//接口
public interface Door{
void open();
void close();
void alarm();
}
open和close这两个方法也必须去实现,也许这个类根本不具备open和close这两个功能,所以应该把open和close放在抽象类中,alarm放在接口中。
24、子类中所有的构造方法默认都会访问父类中无参的构造方法,为什么呢?
1)因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
2)每一个子类构造方法的第一条语句默认都是:super()
25、String、StringBuffer和StringBuilder的区别
1)String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。比如,再次给a赋值时,并不是对原来堆中实例对象进行重新赋值,而是生成一个新的实例对象,并且指向“456”这个字符串,a则指向最新生成的实例对象,之前的实例对象仍然存在,如果没有被再次引用,则会被垃圾回收。
2)StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。StringBuffer对象是一个字符序列可变的字符串,它没有重新生成一个对象,而且在原来的对象中可以连接新的字符串。
3)StringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。
26、在使用包装类类型的时候,如果做操作,最好判断是否为null
27、两种常规Map性能
1)HashMap:适用于在Map中插入、删除和定位元素。
2)Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
3)HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。
28、匿名内部类
前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类
格式:new 类名或者接口(){
重写方法;
};
本质:是一个继承了该类或者实现了该接口的子类匿名对象
29、多态问题:编译看左边,运行看右边 是什么意思?
多态:People p = new Children();
对于成员方法:编译看左边,运行看右边。
对于成员变量:编译运行都看左边。也就是成员变量没有多态特性。
静态方法和变量:编译运行都看左边,同成员变量一样。
编译时候,看左边的对象有没有该方法,运行时候结果看new的对象是谁,就调用谁的方法
30、对象引用和对象的区别
Demo demo=new Demo();
这一条语句,其实包括了四个动作:
1)右边的“new Demo”,是以Demo类为模板,在堆空间里创建一个Dem对象。
2)末尾的()意味着,在对象创建后,立即调用Demo类的构造函数,对刚生成的对象进行初始化。
3)左边的“Demo demo”创建了一个Demo类引用变量,它存放在栈空间中。也就是用来指向Demo对象的对象引用。
4)“=”操作符使对象引用指向刚创建的那个Demo对象。
31、重写和重载
重写是子类的方法覆盖父类的方法,要求方法名和参数都相同,重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同
32、java多线程的几种实现方式:
1)继承Thread类,重写run方法
2)实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3)通过Callable和FutureTask创建线程
4)通过线程池创建线程
33、beak、return、continue的区别
break:直接结束一个循环,跳出循环体。break以后的循环体中的语句不会继续执行,循环体外面的会执行
continue:中止本次循环,继续下次循环。continue以后的循环体中的语句不会继续执行,下次循环继续执行,循环体外面的会执行
return:return的功能是结束一个方法。 一旦在循环体内执行return,将会结束该方法,循环自然也随之结束。与continue和break不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。
34、变量赋值问题
public class Demo {
//成员变量
int a;
Integer b;
public static void main(String[] args) {
Demo demo=new Demo();
//基本数据类型
System.out.println("-------成员变量--------");
System.out.println("基本数据类型:"+demo.a);
//引用数据类型
System.out.println("引用数据类型:"+demo.b);
System.out.println("-----------------");
//局部变量
int c=1,d=2,temp;
temp=c>d?c:d;
System.out.println("局部变量c的值为:"+c);
System.out.println("局部变量d的值为:"+d);
System.out.println("局部变量temp的值为:"+temp);
}
}
1)成员变量可以不用赋初值,在new对象的时候,系统会默认设置一个初值,基本数据类型赋为0,如果是引用类型的成员变量则会赋值为null。
2)方法内(包括main方法,main方法内的变量也是局部变量,只不过它的生命周期和全局变量一样长而已)的局部变量执行进栈操作,在参与运算之前必须赋初值才能使用。c,d参与了运算,所以必须初始化,temp只负责接收表达式的值,不需要初始化。
注:建议无论成员变量还是局部变量,定义之后都赋上初值
35、常量赋值问题
public class Demo2 {
final int i;
static final int j=40;
public Demo2() {
i=20;
}
public static void main(String[] args) {
Demo2 demo2=new Demo2();
System.out.println("无static修饰的常量:"+demo2.i);
System.out.println("有static修饰的常量:"+demo2.j);
}
}
1)用final关键字修饰的常量,可以在其定义时就初始化,也可以到类的构造方法里面再对它进行初始化
2)用static和final关键字同时修饰的常量就必须得再定义时初始化
36、静态常量、普通常量、静态变量、普通变量值能不能被改变问题
public class Demo3 {
//普通常量和静态常量,无论哪种常量,赋值之后,其值就不能被改变
final int a =10;
static final int b=20;
//普通变量和静态变量
static int c=30;
int d=40;
public static void main(String[] args) {
Demo3 demo1=new Demo3();
Demo3 demo2=new Demo3();
demo1.d=45;
demo2.c=35;
System.out.println("第一实例调用普通变量的值"+demo1.d);
System.out.println("第一实例调用静态变量的值"+demo1.c);
System.out.println("第二实例调用普通变量的值"+demo2.d);
System.out.println("第二实例调用静态变量的值"+demo2.c);
}
}
1)普通常量和全局常量,无论哪种常量,一旦赋值之后,其值就不能被改变
2)可以看见静态变量(类变量)无论创建几个实例去改变其值,它的值都将保持最后更改的状态(c值==35)。而普通变量(实例变量)先变成更改后的值(d==45),最后又回到更改前的值(d==40)。 静态变量的值是唯一的(在内存中只有一次拷贝,JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配),但不是不变的,在其作用范围内,只存在一个值,无论在作用域的哪里调用,不管实例化多少对象,改变的都是同一个内存地址,被类的所有实例共享。对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,相互独立且互不影响。
3)一般在对象之间共享值时或者方便访问变量时会使用到静态变量。静态变量(静态方法)通常是为了提供共享数据(方法)。比如:圆周率π,除了圆类需要这个值,在另外一个球类也需要使用。这时候没必要在两个类中同时创建π,因为这样系统会将这两个不在同一类中定义的静态值分配到不同的内存空间中。为了解决这个问题,可以将π设为静态的,在其在内存中共享。
4)对于静态变量来说,可用类名.变量直接访问(推荐),也可以通过对象实例来访问(不推荐)。静态变量(方法)尽量不要实例化调用,会造成内存空间的浪费。对于实例变量,一般通过对象实例访问。静态变量(方法)属于类,非静态变量(方法)属于类的实例。
注:后续将不断补充和完善内容