java基础个人笔记

本文深入讲解了程序设计的基础概念,包括循环控制结构如while和if的区别、数据存储机制如栈和堆的区别、集合与数组的概念及其操作方法、泛型的使用、线程同步机制、反射机制、设计模式等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集合就是可延长的数组


本地回环地址: 127.0.0.1   本机名: localhost


端口号    有效端口: 0--65535,  其中0-1024端口被系统使用或者保留


传输协议有 tcp  。  udp 两个、


while和 if 的区别:::::
if 只做判断,判断一次之后,便不会再回来了
while 的话,循环,直到结果为false,才跳出来


try catch块中的    finally 存放的 一般都是释放资源的动作


栈内存空间小于   堆内存空间
栈    凡是局部变量都 存储在栈内存里面
main函数执行时,会在栈内存中开辟空间,主函数调用方法时也会为方法开辟空间
当方法执行完毕时,会自动释放内存空间


堆    使用关键字 new  出来的实体  都存储在  堆  内存里
堆里面的每一个实体都有 一个内存地址值
堆内存的变量都有默认初始化值
当堆内存的实体 没有任何引用使用它的话 ,不会被立刻回收。会不定时被垃圾回收器回收


选择排序  ,冒泡排序   , 效率是比较低的
排序中最快的排序方式是    希尔排序 ::因为它在栈内存临时存储
普通的数组元素位置交换是发生在    堆内存    中的,而堆内存中换位置比较消耗资源


当类中要操作的引用数据类型不确定的时候   ,
需要定义泛型来解决




高级for循环的极限性,  ,,,必须有被遍历的目标,且不能对被遍历collection进行操作
迭代器除了遍历,还可以进行remove操作,,如果用ListIterator,还可以在遍历中增删改查
高级for循环 可以对 数组  , 对list集合,   对set,集合记性遍历
但是在遍历数组时,  还是建议用传统for,。因为传统for可以顶定义角标





静态方法不可以访问    类上定义的泛型。如果静态方法类型不确定,可以将泛型定义在方法上
方法上定义泛型 如 public <Q> void method(Q q)
静态方法定义泛型如 public static <T> void method(T t)
泛型定义在 返回类型符的 前面    ,   修饰符的后面


泛型限定    如     public static void print(ArraList<? extends Person> a1){}     这个是上限定 
ArraList<? extends Person>
public static void print(ArraList<? super Person> a1){}   这个是下限定


api      就是  application programming interface


hasptable  底层是哈希表数据结构 ,不可以存入null键和null值,该集合线程是同步的 ,
并且效率低     ,    出现在jdk1 1.0版本
haspmap  底层是哈希表数据结构, 可以存入null键和null值,  该集合线程是不同步的,
并且效率高  ,    出现在jdk      1.2版本
treemap   底层是二叉树的数据结构, 线程不同步,   可以用于给map集合中的键进行排序
因为线程不同步的原因, 所以性能上要比 同步的优越一些 ,  但是要自己管理线程上的同步问题
基本上集合跟它的父类是不同写法的,都是不同步的, 如   vector就是线程不同步。它是list的子类
set集合跟 map集合很像。     其实   set 底层使用的就是  map集合 

map 集合   如果想key 和  value  都取出的话    必须用  到 keyset ,和entryset
   因为map集合是 没有 迭代器   ,     而 set  集合  具备迭代器


构造块:直接在类中定义且没有加static关键字的代码块称为{}  构造代码块。
构造代码块在创建对象时被调用,每次创建对象都会被调用,
并且构造代码块的执行次序优先于类构造函数。
1。 静态代码块不能存在于任何方法体内。2
 2. 静态代码块  不能 直接访问类的实例变量和实例方法,需要通过类的实例对象来访问。


final  被final修饰的类 不能被继承,  即没有子类。
被final 修饰的方法 不能被子类 重写,但可以重载多个final修饰的方法
而且 如果方法中再被 private修饰的话,直接导致子类不能继承此方法


一个类要被 使用  必须经过装载,链接 ,初始化这样的过程 ,  由java虚拟机完成





单例设计模式  :   有三大类 :1.懒汉式设计模式 ,就是在第一次调用自己时,实例化
存在线程安全问题,有三种解决方式
2.饿汉式设计模式,在类加载时就创建了实例,
不存在线程安全问题
3.登记式设计模式, 登记式单例实际上维护了一组单例类的实例,
将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,
则从Map直接返回,对于没有登记的,则先登记,然后返回。
其实内部实现还是用的饿汉式单例


反射是基于框架的 ,  想要看懂框架必须 看得懂 反射,  框架一般来说是基于配置文件的。


反射第一步,就是加载类,  Class.forName("类的全路径名"); 得到返回相关联的class对象


private私有的东西能被外界访问吗?
不可以,只能被类的内部访问        但是      反射可以做到这一点  Constructo.setAccessible(true);
 
取map集合内的数据有两种方式


方式一,用 map.keySet();


方式二,用map.entrySet();
Set set = map.entrySet();
Iterator iter = set.iterator();
while(iter.hasNext()){
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
String value = (value) entry.getValue();


}


增强for循环只能用于读取数据 , 不能不能不能用于 修改数据


 基本数据类型的数组 它整个就是一个特殊的对象,     
其他数据类型的数组 ,  它就是一个对象数组


基本数据类型:使用时需要赋具体值,判断时使用“==”号
引用数据类型:使用时可以赋null,判断时使用equals方法
==比较的是两个变量的内容 ,如果是引用类型的话,他们的栈内容就是引用的地址值


char[]是字符数组 byte[]是字节数组
java基本数据类型就 8 种  , 四类八种
第一类:    整型     byte,short,int,long
第二类:    浮点型 float,double
第三类;    逻辑型 boolean
第四类;    字符型 char
除了这些基本数据类型之外, 其他都是引用数据类型    ,  
引用数据类型也有 三大种类  , array数组   String字符串  其他
引用数据类型:类、接口类型、数组类型、枚举类型、注解类型;
基本数据类型也有引用类型,byte  , Byte ,像这样等等类似


HashSet  ,HashMap数据结构是哈希表,线程是不同步的。
注意:::如果想线程同步安全,又想用map的话,使用ConcurrentHashMap代替
保证元素的唯一性原理,判断元素的hashcode值是否相同。
如果相同,还会继续判断equals方法,是否为true。


TreeSet使用二叉树原理,可以对Set集合中的元素进行排序、
使用自然排序方式,但如果键为自定义类,则必须通过实现comparable
的compareTo进行排序判断。另一种方式就是自定义一个comparator实现类
比较器new TreeSet( myComparator);


statement 和PreparedStatement 的区别;
1.PreparedStatement 是statement 的子类;
2.PreparedStatement 可以防止sql注入问题,通过对用户的输入进行转义
3.PreparedStatement 具有预编译功能,可以减轻数据库压力


什么时候使用 map  集合呢????、、???
当发现有 映射关系 时,       可以选择 map 集合    
因为吗map 集合中存放的就是映射关系。


String 和 StringBuilder 和 StringBuffer 的区别:
1.   String 类 因为有final 修饰符, String 内部成员是不可以修改的,而其他两者可以修改
String 的本质就是    char [ ]  + 操作
共同点:         StringBuilder 和 StringBuffer  实现了相同的接口   abstractStringBuilder
2。因为 StringBuffer 对方法加了同步锁,所以线程是安全的,StringBuilder线程不安全
3。如果程序不是多线程的,那么使用StringBuilder 效率高于 StringBuffer
实际中应用 StringBuffer 的比较多


抽象类 和 接口 的区别:
语法层面上的区别:
1,抽象类可以提供各种成员方法的实现细节,而接口只能存在public abstract方法
2,抽象类的成员变量可以是各种类型,而接口的只能pubilic static final类型
3,抽象类可以包含静态代码块和静态方法,而接口不能
4.,一个类只能继承一个抽象类,但是可以实现多个接口
设计层面上的区别:
1,抽象类是对事物的抽象, 接口是对行为的抽象。
如飞机和鸟,他们都是各种飞机和各种鸟的类的统称,而飞则是一种行为,无法抽象成类
2,抽象类是模板设计模式,而接口是辐射式设计模式
如修改抽象类等于修改他的子类,是个模板,而每个实现接口的类,都有自己对这个行为的解释
辐射式设计模式,一旦标准改变,所有的从属也要相应改变。


javabean 的属性     不由     它的  字段   的多少来决定的
是由它的  get或set 方法来决定的
别忘了object类  也有一个getClass() 方法     


mid = ( max + min )>>1;               //         ./2  
Connections
把数组变成 list集合有什么好处?   Arrays.aslist(String[] xx   );
可以使用集合的思想 和 方法  来操作数组中的元素,因为数组方法功能比较少
注意  : 将数组变成集合,不可以使用集合的  增删方法
因为数组的长度是固定的
注意:    如果数组中的元素都是对象,也就是非基本数据类型,那么编程集合时,
数组中的元素    就直接转成     集合的元素
如果数组中的元素就是  基本数据类型,那么会将该数组作为集合中的元素存在
为什么要把 集合    变成  数组 
为了限定对元素的操作
当把 集合 变成 数组 是要注意    使用以上方法  arrayList.toArray(new String[arrayList.size()]);
当注定类型的数组长度 小于 集合的size  


Properties 是HashTable的子类, 也就是map集合的一个子类对象
可以通过map 的方法去除该集合中的元素
该集合存储的都是String  没有泛型定义
System.getProperties();可以获取系统的配置信息


一个类   最多 只能 继承一个类
一个类可以  实现多个  接口


多线程问题 写多线程时,  ,,,必须小心安全问题
如果先要多线程共享一个实例变量,  就要把实例变量定义为    静态变量
应为静态变量只能 有一个实例    ,即 多个改类的对象  共享一个实例变量
如果一个线程创建了    并且 运行过一次 start();方法了
就不能再 调用start方法;  否则会抛出异常   正在运行的线程,不能调用该线程start()
虽然实现多线程有两种方法  ,  继承Thread  或者 实现Runnable
但是真正创建线程的只有Thread类 或其后代才可以


那么问题来了实现方式和继承方式有什么区别呢?????
1.实现方式的好处  ,避免了 单继承的  局限性,所有建议使用实现的方式
2.继承thread 的线程代码存放在thread 子类run方法中
而实现runnable , 线程代码存放在接口的子类的 run方法中


多线程在操作共享数据时 ,特别要留意  执行共享数据的语句, 很容易引发线程安全问题


 同步有两种方式,一种是同步代码块,另一种是同步函数。。同步静态函数,,,,,
这个对象就相当于一个锁
同步的前提: sychronized(对象){ }
1.不须要有多线程 } 同步函数的锁是 this
2、必须是多个线程使用同一个锁 public sychronized void show(){
} 同步静态函数用锁是该类的字节码文件对象 类名.class
必须保证同步中只能有一个线程在运行 public static sychronized void show(){
} 因为静态进内存时,内存中没有本类对象
好处:  解决了多线程的安全问题
弊端:   多个线程需要判断锁,   较为消耗资源


同步锁  有死锁  :::就是因为存在         同步锁的嵌套  ,  如下
线程一     sychronized(Locka){ 线程二 sychronized(LockB){
sychronized(LockB){ sychronized(Locka){
} }
} }


线程间的通讯:::::
其实就是多个线程在操作同一个资源, ,但是操作的动作不同
线程间的通讯,,,多使用等待唤醒机制     wait();    notify();  还有一个notifyAll();
线程运行时,内存中会建立一个线程池。 等待的线程都存放在线程池中
notify();唤醒的是谁,通常唤醒第一个被等待的。
注意注意:::::: wait();    notify();  还有一个notifyAll(); 
因为要对持有       监视器(锁)        的线程操作,而只有同步才具有锁
为什么以上这些方法要定义在object类中呢????????
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有锁
只有同一个 锁 上的被wait等待线程,才能被同一个锁notify唤醒
注意::不可以对不同锁中的线程唤醒。
也就是说 等待和唤醒,必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在object中
在jdk1.5后       Lock对象代替了  sychronized代码块和sychronized对象
Condition对象 代替了   监视器(锁)的: wait();    notify();  还有一个notifyAll(); 
出现这些对象的一大好处是。,Lock 可以 new 出多个 Condition对象
意味着一个锁可以   分开wait      分开唤醒, 而不需要通过notifyAll(); 唤醒全部线程
两段需要同步的代码,共享一个锁 ,却可以唤醒对象,而自己wait();

如何停止线程????????????
只有一种方法,,,就是让run方法结束掉,线程通常都是循环的,
只要控制住循环,,,,就能让run   方法结束,也就是线程结束
通常是做一个标记位,,,flag;
特殊情况:::::::::::
当线程处于冻结状态,,就不会读取到循环的标记位,线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结状态进行清除
强制让线程恢复到运行状态中来,这样就可以操作标记位 让线程结束
thread类提供了一个这样的方法,,,,thread.interrupt();
会抛出异常。这时应该在catch代码块中  改变flag


守护线程或者用户线程  是什么意思呢??? 其实可以理解为 ::后台线程
后台线程的特点是,,开启后,和前台线程共同抢劫cpu的资源
开启运行都没什么区别,区别是  结束时,
当所有的前台线程结束时,,,所有的后台线程会自动结束,你在我故我在
为什么称之为守护线程呢,,,,,就是守护前台的线程,守护对象没了,自己也没了


thread.join();??????????????????????????????????????????????j
当A线程执行到了B线程的 threadB.join();时,A就会等待。等B线程都执行完,A才会执行


设计模式::
单例 ,,工厂,,观察者模式,,装饰设计模式,,适配器,,组合模式
组合模式::部分和整体  在外面面用起来 具有   一致性


java  对象  存放在 ~~~ 堆  ~~~~~内存空间里


服务是不能直接new出来    new出来的服务只能是普通的对象
服务的对象  是被系统(框架)new 出来的


面向对象::::
在开发过程的一种    方法论




字符输出流   需要读取完数据后 需要刷新才能输出也就是
write();
flush();
但是   字节流 ,读取完数据,,可以不需要刷新缓冲数据
write();就可以了


其实字符流底层
用的也是 字节流 的缓冲区


file:::
createrNewFile();方法,可以在指定位置创建文件夹,如果该文件已经存在,
则不创建。和输出流不一样,输出流对象一建立文件,且文件存在,就会覆盖


如果通过反射 调用 对象里面的方法的话:
如果方法的参数是 可变参数,,或者 参数是 数组[]的话,
就要在 你想要传的数组参数外面再包裹一个数组object[],
另一种方法是,,把数组 强行转化为 object对象
这是因为jdk1.5新出的可以数组,需要向下兼容导致的



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值