java基础学习(一)
1.内部类
- 通过外部类创建内部类:成员内部类
Outer outer = new Outer();
//通过这个外部类来实例化内部类~
Outer.Inner inner = outer.new Inner();
//内部类可以获得外部类的私有属性和方法
-
一个java类中可以有多个class类,但是只能有一个public class
-
局部内部类:
public Class Outer{ //局部内部类 public void method(){ class Inner{ public void in(){ } } } }
-
匿名内部类
public class Test{
public static void main(String [] args){
//没有名字初始化类,不要将实例保存在变量中
new Apple().eat();
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
2.String(不可变内容,不可变字符序列)、StringBuilder类、StringBuffer类
-
String类常用方法:
public int indexOf(String str) public int indexOf(String str,int fromIndex) public String substring(int start) public String substring(int strat,int end) public int length() char charAt(int index) //创建并返回一个新的String对象:concat()、replace()、 //substring()、toLowerCase()、toUpperCase()、trim() //提供查找功能的有关方法:endsWith()、startsWith()、 //indexOf()、lastIndexOf() //提供比较功能的方法:equals()、equalsIgnoreCase()、 //compareTo() //其他方法:charAt()、length()
-
StringBuilder:因为不做线程同步检查,所以效率高,但是线程不安全。因为底层数组变量没有被final修饰,所以是可变字符序列。
-
String 类、StringBuilder、StringBuffer存储字符时,分别依赖的是数组属性。
-
因为String类的底层是用final来修饰所依赖的数组属性,所以String类是一个不可变序列,每次都会创建新的String对象,因此这对内存来说非常不友好。
-
由于StringBuilder/StringBuffer类的底层没有用final来修饰所依赖的数组属性,所以StringBuilder/StringBuffer是可变字符序列,不会创建新对象,内存可读性非常好。
3.垃圾回收
- 垃圾回收过程一般分为几步? 发现垃圾和回收垃圾
- 垃圾回收常见的两种算法?
- 堆内存划分为:年轻代、年老代、永久代 ,对应的垃圾回收器:Minor GC、Major GC、Full GC。
- 对于JVM调优的过程中,很大一部分工作就是对于Full GC的调节
- System.gc()建立启动垃圾回收线程,而不是自己来调用垃圾回收线程
4.this
-
this的本质就是”创建好的对象的地址“ 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表”当前对象“。
-
this()可以用于调用其他构造器,但是必须位于调用方法体的第一行。
-
this不能用在static修饰的方法当中,因为该方法没有从属的对象,所以不能使用this关键字。
5.static
- jvm:
- 1.在方法区加载用来表示类信息(类中的代码、静态变量、静态方法)的一个对象。
- 2.然后栈中就存在一个的对象,堆中也生成了引用地址并把该引用给了栈中的一个对象,栈指向堆内存。
- 3.然后堆指向方法区,根据引用地址去寻在对应的资源。
- 静态方法和静态变量属于类,而this是指对象地址,所以this不能用在static的方法里。
- 静态方法不能使用普通方法和普通变量,而普通方法中可以使用静态方法和静态变量。
6.String类
-
String类是一个不可变字符序列,不可变序列就是对象的值不可变,每次给对象重新赋值都会创建一个新的String对象,这对内存非常不友好,可能会造成内存泄露问题。与之相反的是StringBuilder和StringBuffer类都是属于可变字符序列,就是对象的值是可变的,每次给对象重新赋值,都不会创建一个新对象,重复使用同一对象,这样就可以减少内存空间消耗。StringBuilder类他是线程不安全的,因为执行时没有检查同步锁,所以运行效率高;而StringBuffer类是线程安全的,由于执行时会检查同步锁,因此运行效率要低于StringBuilder。推荐在开发中去使用StringBuilder类,增强运行效率,同时减少内存消耗。其中StringBuilder类中经常使用append方法来连接字符串来实现拼接。
-
字符串是存放在方法区的常量池当中的,然后把常量池的地址给栈中str2和堆中的对象s;堆中的对象s的地址给栈中的str1,然后根据引用地址找到对应的值。字符串比较就是用equals方法。
7、Object
面向对象
封装:安全,屏蔽细节,保护逻辑正确性
继承
多态:行为多态、对象多态,向上转型(父类(超类)引用去接受子类(派生类)对象)过程中是先有的派生类,再有的超类。
重写:
方法名一样,参数列表一样,返回值一样。
重写一个类的toString方法,将当前对象转为字符串,该字符串包含该对象的属性信息。很多java的api会直接调用对象的toString方法。直接输出对象。
equals方法
Object的equals比较的是地址,本身内部就是用“==”进行比较的,没有实际意义,所以在我们定义的类需要使用equals时,就需要重写equals方法。
重写后的equals比较的是内容。
重写equals方法
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(this==obj){
return true;
}
if(obj instanceof Point){
Point p=(Point)obj;
return this.x==p.x && this.y=p.y;
}
return false;
}
而java API提供的类,toString,equals方法都妥善上进行了重写。
8、包装类
java不是完全面向对象的语言,因为八大基本数据类型是以值的形式存在。
包装类是为了解决基本类型不能直接参于面向对象开发的问题。
其中6个数字类型的包装类继承自Number类。
java.lang.Number是个抽象类,定义了几个
抽象方法,要求数字类型的包装类可以将其表示的数字以任意数字类型返回。
String.valueof()
Integer.parseInt()
Double.parseDouble()
9.稀疏数组
稀疏数组:
数组是一种数据结构,当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是: 记录数组一共有几行几列,有多少个不同值 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而小缩小程序的规模
10、爬虫原理
//条件:允许浏览器访问,允许爬虫读取
//以下为解决方案
public static void main(String[] args) throws Exception {
//获取URL
URL url =new URL("https://www.jd.com");
//下载资源
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,"utf8"));
String msg=null;
while(null!=(msg=br.readLine())) {
System.out.println(msg);
}
br.close();
//分析
//处理
}
//条件:允许浏览器访问,不允许爬虫读取
//以下为解决方案:
public static void main(String [] args) throws Exception{
//获取URL
URL url =new URL("https://www.dianping.com");
//下载资源
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36");
BufferedReader br =new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
String msg =null;
while(null!=(msg=br.readLine())) {
System.out.println(msg);
}
br.close();
}
11.socket:是传输层给应用层打开的一个小口,把数据放在里面,不需要我们去关心具体实现,这叫做“套接字(插座)”
-
传输层有两个协议:UDP和TCP
-
UDP:传输基本数据类型,使用DATA流(或Object流);如果是引用类型(对象),使用Object流;通过包进行传输,包里面写地址,性能高,不安全。一切都是转成字节数组来传输
-
TCP:安全,性能较低;利用io流完成数据传递;tcp是http的底层传输协议;