黑马程序员---java学习笔记之java加强(一)

1、myeclipse是eclipse的一个插件。

2、高版本的java可以运行低版本的javac编译的程序,低版本的java不可以运行高版本的javac编译的程序。

3、ide开发工具支持使用工程化方式管理一个项目的开发。

4、所谓静态导入就是导入某个类中的一个或多个或所有静态方法。

5、可变参数的特点:

        a):可变参数只能放在参数列表的最后;

        b):...位于可变参数数据类型和该可变参数变量名之间;

        c):给含有可变参数的参数列表传递数值时,该列表隐含地使用一个数组类接受多个参数,在该参数列表下面的方法体中可以通过数组访问的形式获取各个参数值,

6、myeclipse中多行注释的快捷键是“ctrl+shift+/”。

7、加强的for循环,它所循环的集合或者数组需要实现Iterable接口。

8、自动拆箱和自动装箱

//该过程包含将int型数值4,自动封装成对象,然后将该对象的引用赋给i
		//这个过程称为自动装箱
		Integer i = 4;
		
		//i+3对象引用i自动转变成int型数值然后进行计算
		//这个过程称为自动拆箱
		System.out.println(i+3);
9、下面看String对象的一个特点:

String s1 = "abc";
		String s2 = "abc";
		
		System.out.println(s1 == s2);//打印结果为true
意思就是说,当内存中存在一个“abc”对象实体时,再创建一个相同内容的字符串时,就不会再在内存实体中创建该对象实体了,而是让新创建的对象引用指向原有的对象实体。

10、

                Integer i1 = 13;
		Integer i2 = 13;
		System.out.println(i1 == i2);//打印结果为:true
		
		Integer i3 = 134;
		Integer i4 = 134;
		System.out.println(i3 == i4);//打印结果为:false
        由该示例引出一个一个知识点,在int型数值自动装箱时,该数值的范围在-127~128时,如果内存中已有该值的对象实体,就不在创建新的对象实体,这称为 享元模式;该数值的范围不在-127~128之内,就创建新的对象实体。

11、枚举入门示例:

另外,个人认为枚举类是一个内部类。

public static void main(String[] args) {
		
		Weekday weekday = Weekday.Mon;
		//返回该对象的名字
		System.out.println(weekday.name());
		//返回该对象的队列位置
		System.out.println(weekday.ordinal());
		
		//将相应字符串与枚举序列中的某个对象对应起来
		System.out.println(Weekday.valueOf("Sun"));
		
		//列举出所有的枚举对象,然后使用加强for循环遍历输出
		Weekday[] weekdays = Weekday.values();
		
		for( Weekday wee : weekdays)
			System.out.print(wee+" ");

	}
	public enum Weekday
	{
		Sun,Mon,Tue,wed,Thu,Fri,Sat
	}
12、带有构造器的枚举序列

public enum Weekday
	{
		
		Sun,Mon(1),Tue,wed,Thu,Fri,Sat;
		private Weekday(){}
		private Weekday(int day){}
		
	}
需要注意的有以下几点:

        a):构造函数应该写在枚举对象序列的后面,并且枚举序列的后面应该加分号,以与后面的构造函数隔开;

        b):构造函数必须是私有的;

        c):当枚举类被用到,创建各个枚举序列对象时,默认调用的是无参的构造函数;要想调用含相应参数的构造函数,需在相应枚举对象的后面加上(相应参数)。

13、含有抽象函数的枚举对象序列的写法

public enum TrafficLamp
	{
		RED
		{
			@Override
			public TrafficLamp nextLamp() {
				return YELLOW;
			}
			
		},
		GREEN
		{
			@Override
			public TrafficLamp nextLamp() {
				return RED;
			}
			
		},
		YELLOW
		{
			@Override
			public TrafficLamp nextLamp() {
				return GREEN;
			}
			
		};
		
		public abstract TrafficLamp nextLamp();
	}
14、反射在java1.2就存在了,类Class是反射的基石。

15、得到字节码对象的三种形式:

        a):类.class,示例:Class c = String.class;

        b):使用类Object中的getClass()方法,示例:Class c = new String().getClass();

        c):使用类Class中的forName()方法,示例如下:Class.forName("java.lang.String")。

16、九个预定义的Class实例对象:boolean.class,byte.class,int.class,char.class,long.class,float.class,double.class,short.class以及void.class

17、使用三种方法得到某Class文件对象,然后验证三种方法得到是否是同一个Class文件对象。

		String str = "abc";
		
		Class c1 = str.getClass();
		Class c2 = String.class;
		Class c3 = Class.forName("java.lang.String");
		
		System.out.println(c1 == c2);//打印结果为true
		System.out.println(c1 == c3);//打印结果为true
由打印结果可知,三种方法所得到的对象是同一个Class文件实例对象。

18、Class中的isPrimitive()方法是验证该Class实例对象是不是基本数据类型的(又称为“原始数据类型的”)

System.out.println(String.class.isPrimitive());//打印结果为:false
		System.out.println(int.class.isPrimitive());//打印结果为:true
		System.out.println(void.class.isPrimitive());//打印结果为:true
注意,void.class.isPrimitive()的返回值为true。
19、一个小知识点:

System.out.println(int.class == Integer.class);//打印结果为:false
		System.out.println(int.class == Integer.TYPE);//打印结果为:true
Integer类中的TYPE值表示的它所封装的基本类型的Class实例对象。以此类推

System.out.println(double.class == Double.class);//打印结果为:false
		System.out.println(double.class == Double.TYPE);//打印结果为:true
		
		System.out.println(boolean.class == Boolean.class);//打印结果为:false
		System.out.println(boolean.class == Boolean.TYPE);//打印结果为:true
20、另外,

System.out.println(int[].class.isPrimitive());//打印结果为:false
		System.out.println(int[].class.isArray());//打印结果为:true
数组类型的Class实例对象不是基本数据类型的,另外判断一个Class实例对象是不是数组型的使用的是Class类中的isArray方法。

21、只要在java源程序中出现的类型都有对应的Class实例对象。

22、反射的概念:把java类中的各种成分映射成相应的java类。

        a):Constructor类

                1):Class类中的getConstructors()可以得到所有的公共构造方法对象数组;

                2):Class类中的getConstructor(Class ... t)获取含有某一特定参数变量的构造函数;

                3):Class类中newInstance()和Constructor类中的newInstance(相应参数)的区别是在于,前者只能创建无参的对象,后者可以创建该类可创建的任意参数的对象。另外,Class类中的newInstance方法的实质其实是通过Constructor类创建无参构造函数对象。

        下面是使用构造函数创建对象的代码示例:

Constructor c = String.class.getConstructor(StringBuffer.class);
		
		String str = (String)c.newInstance(new StringBuffer("abc"));
        这个方法并没有使用new的方法创建对象。

        b):Field类

         示例如下:

import java.lang.reflect.Field;

public class ReflectPoint {

	private int x;
	public int y;
	
	
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}


	public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		
		ReflectPoint rp = new ReflectPoint(3,5);
		
		Field f = rp.getClass().getField("y");		
		System.out.println(f.get(rp));
		
		//一下代码演示了,怎样获取一个类中的私有字段的方法,主要有两点:
		//1、使用getDeclaredField方法获取目标类私有字段的示例对象
		//2、使用setAccessible方法把该字段设置为可访问的。
		Field f1 = rp.getClass().getDeclaredField("x");
		f1.setAccessible(true);
		System.out.println(f1.get(rp));
		
	
	}

}
另一份代码,修改某一个类的示例对象的字段值

import java.lang.reflect.Field;

public class ReflectPoint {

	private int x;
	public int y;
	public String str1 = "ball";
	public String str2 = "basketball";
	public String str3 = "itcast";
	
	
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString()
	{
		return str1+"  "+str2+"  "+str3;
		
	}

	public static void main(String[] args) throws Exception {
		
		ReflectPoint rp = new ReflectPoint(3,5);
		
		changeStringValue(rp);	
		
		System.out.println(rp.toString());
	
	}


	public static void changeStringValue(Object obj) throws Exception {
		
		Field[] fields = obj.getClass().getFields();
		
		for( Field field : fields )
		{
			if(field.getType() == String.class)
			{
				String oldValue = (String)field.get(obj);
				String newValue = oldValue.replace('b', 'a');
				field.set(obj,newValue );
			}
		}
		
		
	}

}
        c):Method类

String str = "dasfjashfla";
		Method method = Class.forName("java.lang.String").getMethod("charAt",int.class);
		
		System.out.println(method.invoke(str, 3));
当调用的某个类中的静态方法是,invoke的第一个参数就设置为null。

        使用反射的方式在一个类中调用另一个类中的main函数。

public class ReflectDemo {
	public static void main(String[] args) throws Exception
	{
		Class.forName("cn.itcast.repeat.Test").
		getMethod("main", String[].class).
		invoke(null, new Object[]{new String[]{"123","456","789"}});
		
	}
		
}
	
class Test
{
	public static void main(String[] args)
	{
		for(String arg : args)
		{
			System.out.println(arg);
		}
	}
}
23、两个数组的Class实例对象是否相等的判断条件是:两数组是不是有相同的维度,两数组所含元素是不是相同的数据类型。

24、介绍一种错误的形式:

Object[] obj = new int[3];
上述代码是不能通过编译的,因为基本类型的int不是Object的子类。而下面这种却可以

Object[] obj = new int[3][5];
这说明,int[]是Object的子类。也可以推广来说, 基本数据类型的一维数组都是Object类的子类。下面使用反射的形式来验证:

int[] a1 = new int[3];
		
		System.out.println(a1.getClass().getSuperclass().getName());
		//打印结果是:java.lang.Object
25、怎样快速打印一个数组中的值?

        答:使用Arrays的toString方法。或者使用Arrays的asList方法(当该一维数组是基本类型的时候就不能打印该数组的所有元素了)。

public static void main(String[] args) throws Exception
	{
		
		int[] a1 = new int[]{1,2,3};
	
		getObjEle(a1);
		
	}

	private static void getObjEle(Object obj) {
		
		Class c = obj.getClass();
		
		if( c.isArray() )
		{
			int len = Array.getLength(obj);
			for( int i = 0; i < len; i++ )
				System.out.println(Array.get(obj,i));
		}
		else
		{
			System.out.println(obj);
		}
		
	}

26、java中有内存泄露吗?为什么?

        答:有的。比如说,HashSet集合中添加了几个对象,这几个对象计算hashCode值的方法用到了这些对象的一些字段。后来这些被用到某个对象的字段的值被修改了,如果此时,要删除HashSet集合中的该元素,就会不能够删掉!因为删除时调用的是当前的hashCode方法计算原对象的哈希地址,原对象在HashSet集合中的地址没变,但是新计算的哈希值却改变了,导致该对象不能被找到。这种不能删除的状况累计下去的话,就可能造成内存泄露。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值