java基础
Java包
JDK 中常用的包有哪些
- java.lang:这个是系统的基础类;
- java.io:这里面是所有输入输出有关的类,比如文件操作等;
- java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
- java.net:这里面是与网络有关的类;
- java.util:这个是系统辅助类,特别是集合类;
- java.sql:这个是数据库操作的类
import java和javax有什么区别
刚开始的时候 JavaAPI 所必需的包是 java 开头的包,javax 当时只是扩展 API 包来说使用。然而随着时间的推移,javax 逐渐的扩展成为 Java API 的组成部分。但是,将扩展从 javax 包移动到 java包将是太麻烦了,最终会破坏一堆现有的代码。因此,最终决定 javax 包将成为标准API的一部分。所以,实际上java和javax没有区别。这都是一个名字
反射
什么是反射机制
- JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任
意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法
的功能称为java语言的反射机制。 - 静态编译和动态编译
静态编译:在编译时确定类型,绑定对象
动态编译:运行时确定类型,绑定对象
反射机制优缺点
优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。
反射机制的应用场景有哪些?
反射是框架设计的灵魂。
在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有
用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节
码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大
量使用到了反射机制。
举例:
①我们在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;
②Spring框架也用到很多反射机制,最经典的就是xml的配置模式。Spring 通过 XML 配置模式装
载 Bean 的过程:
- 将程序内所有 XML 或 Properties 配置文件加载入内存中;
2)Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息;
3)使用反射机制,根据这个字符串获得某个类的Class实例;
4)动态配置实例的属性
Java获取反射的三种方法
1.通过new对象实现反射机制 2.通过路径实现反射机制 3.通过类名实现反射机制
public class Reflect {
//获取反射机制三种方式
public static void main(String[] args) throws ClassNotFoundException {
//方式一(通过建立对象)
Student stu = new Student();
Class classobj1 = stu.getClass();
System.out.println(classobj1.getName());
//方式二(所在通过路径-相对路径)
Class classobj2 = Class.forName("studyText.Student");
//方式三(通过类名)
Class classobj3 = Student.class;
System.out.println(classobj3.getName());
}
}
String相关
字符型常量和字符串常量的区别
形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该
字符串在内存中存放位置)
占内存大小 字符常量只占一个字节 字符串常量占若干个字节(至少一个字符结束标志)
什么是字符串常量池
字符串常量池位于元数据区中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用
String 是最基本的数据类型吗
不是,属于引用数据类型
String 底层就是一个 char 类型的数组 final修饰 不可改变
String为什么是不可变的吗
简单来说就是String类利用了final修饰的char类型数组存储字符,源码如下图所以:
/** The value is used for character storage. */ private final char value[];
String有哪些特性
- 不变性:String 是只读字符串,是一个典型的 immutable 对象,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性。
- 常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。final:使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性
String 类的常用方法都有那些
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
StringBuffer和StringBuilder常见的方法
1.存储
1)append(); //将指定数据加在容器末尾,返回值也是StringBuffer
eg:
StringBuffer sb = new StringBuffer(//可以加str);
StringBuffer sb1=ab.append(数据) //数据可以任何基本数据类型
注:此时sb == sb1他们是同一对象,意思是可以不用新建sb1直接 sb.append(数据) 使用时之后接使用sb
2)insert();// 插入
sb.insert(index ,数据);
3.获取
char c = sb.charAt(index);//获取index上的字符
int i = sb.indexOf(char)://获取char字符出现的第一次位置
//与 String 中的获取方法一致参考前面
4.修改 String类中无次操作方法
sb =sb.replace(start,end,string)//将从start开始到end的字符串替换为string;
sb.setCharAr(index ,char);//将index位置的字符变为新的char
5.反转 sb.reverse();//将sb倒序
6. getChars(int srcBegin,int srcEnd,char[] ch,int chBegin)
//将StringBuffer缓冲区中的指定数据存储到指定数组中
在使用 HashMap 的时候,用 String 做 key 有什么好处?
HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,
所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,相比于其他对象更快。
String和StringBuffer、StringBuilder的区别是什么
- 是否可变性
不可变性
String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的,加了final,也就可以理解为常量,线程安全
可变性
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法这两种对象都是可变的 - 线程安全性
StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以StringBuffer是线程安全的,Buffer这个词 缓冲,在应用程序空间和硬盘空间之间的内存空间(缓冲区)多是线程安全
StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。 - 性能
每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险 - 对于三者使用的总结
如果要操作少量的数据用 = String
单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
包装类相关
Java 为每个原始类型提供了包装类型:
原始类型: boolean,char, byte, short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
装箱与拆箱
将基本数据类型–(转换为)->引用数据类型(装箱)
将引用数据类型–(转换为)->基本数据类型(拆箱)
自动装箱与拆箱
Integer a= 127 与 Integer b = 127相等吗
对于对象引用类型:== 比较的是对象的内存地址。
对于基本数据类型:== 比较的是值。
如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 ==的结果是false
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3; // 将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b); // false 两个引用没有引用同一对象
System.out.println(a == c); // true a自动拆箱成int类型再和c比较
System.out.println(b == c); // true
Integer a1 = 128;
Integer b1 = 128;
System.out.println(a1 == b1); // false
Integer a2 = 127;
Integer b2 = 127;
System.out.println(a2 == b2); // true
}