Java基础(四)

值传递
当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,这是值传递

为何只有值传递
按值调用表示方法接收的是调用者提供的值,而按引用调用表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所 对应的变量值,而不能修改传递值调用所对应的变量值,方法得到的是所有参数值的一个拷贝,方法不能修改传递给他的任何参数变 量的内容。

值传递和引用传递的区别
·值传递
在方法调用时,传递的参数是按值的拷贝传递,传递的值是拷贝,传递后互不相关
·引用传递
在方法调用时,传递的参数是按引用进行传递,传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,传递 前和传递后都指向一个引用(同一个内存空间)。

值传递ex:

public static void swap(int a,int b){
	int temp=a;
	a=b;
	b=temp
	System.out.println("a="+a);
	System.out.println("b="+b);
}
pubic static void main(Stringp[] args){
	int num1=1;
	int num2=2;
	swap(num1,num2);
	System.out.println("num1="+num1);
	System.out.println("num1="+num2);
}

结果:
a=2
b=1
num1=1
num2=2

其中a和b都是num1和num2的拷贝,它们的拷贝进行了交换,但并不影响num1和num2的值

引用传递

public static void swap(int a,int b){
	int[]arr={1,2,3,4};
	System.out.println(arr[0]);
	charnge(arr);
	System.out.println(arr[0]);
}
public static void change(int[] array){
	arr[0]=0;
}

结果:
1
0

对象的值传递

public static void swap(Student x,Student y){
	Student temp=x;
	x=y;
	y=temp;
	System.out.println("x:"+x.getname());
	System.out.println("y:"+y.getname());
}
public String getname(){
	return name;
}

public Student(String name){
	this.name=name;
}
pubic static void main(Stringp[] args){
	Student s1=new Student("xiaoming");
	Student s2=new Student("xiaoli");
	Test.swap(s1,s2);
	System.out.println("s1:"+s1.getname());
	System.out.println("s2:"+s2.getname());
}

JDK中常用的包
·java.lang:系统类基础
·java.io:输入输出有关的类,比如文件操作
·java.nio:完善io包的功能,提高io性能的新包
·java.net:与网络有关的类
·jav.util:系统辅助类,集合类
·java.sql:数据库操作的类

Files常用方法
1.Files.exists():检测文件路径是否存在
2.Files.createFile():创建文件
3.Files.createDirectory();创建文件夹
4.Files.delete();删除一个文件或目录
5.Files.copy();复制文件
6.Files.move();移动文件
7.Files.size();查看文件个数
8.Files.read();读取文件
8.Files.write();写入文件

Java获取反射的三种方法
1.通过new对象实现反射机制
2.通过路径实现反射机制
3.通过类名实现反射机制

ex:

public class Student{
	private int id;
	String name;
	protected boolean sex;
	public float score;
}
public class Get{
	//获取反射机制三种方式
	public static void main(String[] args){
		//方式一(通过建立对象)
		Student stu=new Student();
		Class classobj1=stu.getClass();
		System.out.println(classobj.getName());
		//方式二(所在通过路径-相对路径)
		Class classobj2=Class.forName("fanshe.Student");
		System.out.println(classobj2.getName());
		//方式三(通过类名)
		Class classobj3=Student.class;
		System.out.println(classobj3.getName());
	}
}

常用API
String
字符型常量和字符串常量的区别
1.形式上:字符常量是单引号引起的一个字符,字符串常量是双引号引起的若干个字符。
2.含义上:字符常量相当于一个整型值(ASCII值),可以参加表达式运算,字符串常量代表一个地址值(该字符串在内存中存放位置)。
3.占内存大小:字符常量只占一个字节,字符串常量占若干字节。

字符串常量池
字符串常量池位于堆内存中,用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时,JVM会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回 其引用。

String是最基本的数据类型吗
不是,基本数据类型为byte short long int float double boolean char 8个,剩下的都是引用数据类型
基本数据类型用来描述文本的是char,但它只能表示单个字符,比如’a’,‘你’,如果要描述一段文本,就需要用多个char类型的变量 ,即数组,比如char[]chars={‘1’,‘2’};使用数组过于麻烦,所以就用String,String底层是一个char类型的数组,使用时不需要直 接操作底层数组,用更加简便的方式即可完成对字符串的使用

String有哪些特性
1.不变性:String是只读字符串,是一个典型的immutable对象,对它进行任何操作都是创建一个新对象,再把引用指向该对象。不变模 式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的统一性。
2.常量池优化:String对象创建后,会在字符串常量池中进行缓存,如果下次创建同样对象时,会直接返回缓存的引用。
3.final:使用final定义String类,表示String类不会被继承,提高了系统的安全性

String为什么是不可变的
String类利用final修饰char类型数组存储字符
源码:private final char value[];

String真的不可变吗
不可变
1.String不可变但不代表引用不可以变
String str=“Hello”;
str=str+“World”;
System.out.println(“str=”+str);
原String的内容是不可以变得,只是str由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址,也就是说多开辟了一块内存区域给"Hello World"

2.通过反射可以修改所谓的不可变对象
String s=“Hello World”;
System.out.println(“s=”+s);
//获取String类中的value字段
Field value=String.class.getDeclareField(“value”);
//改变value属性的访问权限
value.setAccessible(true);
//获取s对象上的value属性值
char[]value=(char[])value.get(s);
//改变value所引用的数组中的第五个字符
value[5]="_";
System.out.println(“s=”+s);
s=“Hello World”;
s=“Hello_World”;

·String类是否可以被继承
String类是final类,不可以被继承

·String s=new String(“xyz”);和String s=“xyz”;一样吗
不一样,内存的分配方式不一样,String s="xyz"是java虚拟机将它分配到常量池中;而String s=new String(“xyz”)则被分配到堆内 存中。

·String s=new String(“XYZ”);创建了几个字符串对象
两个对象,一个是静态区的"XYZ",另一个是用new创建在堆上的

String str1=“hello”;
String str2=new String(“hello”);
String str3=“hello”;
String str4=new String(“hello”);
System.out.println(str1.equals(str2));//true,String 重写了equals方法,比较的是两个地址的值是否相同。
System.out.println(str2.equals(str4));//true,String 重写了equals方法,比较的是两个地址的值是否相同。
System.out.println(str1= =str3);//true,String 创建的字符串,如果内容相同则在同一地址,都是在常量池的同一地址。
System.out.println(str1= =str2);//false,地址不同,str1在常量池,str2在堆上
System.out.println(str2= =str4);//false 堆内存位置不同,一个在str2,一个在str4;
System.out.println(str2= =“hello”);//false,str2在堆内存,"hello"在静态区
str2 =str1;
System.out.println(str2= =“hello”);//true,str1和str2地址相等, str1在值为hello的常量池,那么str2也在值为hello的常量池 ,所以为同一地址。

字符串如何翻转
使用StringBuilder或者 stringBuffer的reverse()方法
ex:

StringBuffer stringBuffer =new StringBuffer();
stringBuffer.append("abcde");
System.out.println(stringBuffer.reverse());//edcba

StringBuilder stringbuilder=new StringBuilder();
stringbuilder.append("abcdef");
System.out.println(stringbuilder.reverse());//fedcba

·数组是否有length()方法,String是否有length()方法
数组没有length()方法,有length属性,如Value.length。

String类的常用方法
indexOf():返回指定字符的索引
charAt():返回指定索引处的字符
replace():字符串替换
trim():去除字符串两端空白
split():分割字符串,返回一个分割后的字符串数组
getBytes():返回字符串的byte类型数组
length():返回字符串长度
toLowerCas():将字符串转成小写字母
toUpperCase():将字符串转换成大写字母
substring():截取字符串
equals():字符串比较

·在使用HashMap的时候,用String做key有什么好处
HashMap内部实现是通过key的hashcode来确定value的存储位置,因为字符串是不可变的,所以当创建字符串时,它的hashcode被缓存 下来,不需要再次计算,所以相比于其他对象更快。

string和StringBuffer、StringBuilder的区别是什么,String为什么是不可变的。
可变性
1.String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。
2.StringBuilder和StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串, char[]value,这两种对象可变。

线程安全
3.String中的对象是不可变的,可以理解为常量,线程安全。
4.AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了字符串的基本操作(expendCapacity、append、insert、indexOf)等公共方法,StringBuffer对方法加了同步锁或者对调用方法加了同步锁,所以是线程安全的。
5.StringBuilder并没有对方法进行加同步锁,所以是非线程安全。
性能
每次对String类型进行改变时,都会生成一个新的对象,然后将指针指向新的String对象,StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下,StringBuilder比StringBuffer多10%~15%性能提升,但却冒多线程不安全的风险

总结
操作少量数据用= String
单线程操作字符串缓冲区下操作大量数据用=StringBuilder
多线程操作字符串缓冲区下操作大量数据用=StringBuffer

int和Integer有什么区别
将基本数据类型当成对象操作,每一个数据类型都有对应的包装类型,int类的包装类就是Integer
ex:
原始类型:boolean char byte short int long float double
包装类型:Boolean Character Byte Short Integer Long Float Double

·自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来
拆箱:将包装类型转换为基本数据类型

·Integer a=127和Integer b=127相等吗
对象引用类型: = =比较的是对象的内存地址
基本数据类型: = =比较的是值

ex:

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 b自动拆箱成int类型再和c比较
	Integer a1=128;//如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中			 的Integer对象,超过范围就会new新的Integer对象,导致两个对象地址不同。
	Integer b1=128;
	System.out.println(a1 == b1);//false
	Integer a2=127;
	Integer b2=127;
	System.out.println(a2 == b2);//true
	Integer a1=128;//如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中			 的Integer对象,超过范围就会new新的Integer对象,导致两个对象地址不同。
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值