java 学习笔记

 

关于String

String 有常量池,下面这段代码输出为true;

        String a="aa";
        String b="aa";
        System.out.println(a==b);

数据类型

当有一系列加的运算的时候,如果某个部分其中含有字符串,那么这个字符串前面挨着的+号开始一直往后都是要按照字符串的拼接去看,下面的代码输出9hello

System.out.println(1+3+5+"hello");

java里面参数传递方式只有一种:值传递。即将实际参数值的副本传入方法内,而参数本身不受影响。

JVM内存包括栈(基础类型、对象的引用(地址))、堆(所有的对象)、方法区(所有的class和static变量)

如果方法的形参是基本数据类型,那么实参向形参传递参数时就是直接传递值。

如果方法的形参是对象,那么实参向形参传递参数时也是把参数给形参,这个值是实参在栈内存中的值,也就是引用对象在堆内存中的地址。

基本数据类型都是保存在栈内存中,引用对象在栈中保存的是引用对象的地址,那么方法的参数传递是传递值。

javabean是一种Java语言写成的可重用组件

java只支持单继承,一个子类只能有一个父类

重载:本类中的同名方法,相同的名称实现不同的逻辑;重写:子类对父类方法的覆盖,子类可以使用和父类相同的方法名,覆盖父类的逻辑

java里面==与equals

只有指向对象的时候相等,等于号相等

equals只能比较引用类型,其作用于==相同

对于对象来说

特殊的类,如String、File、Date,使用==比较的是对象(对象的地址),equals比较的内容

除了特殊的类之外的其他普通的类的对象,==和equals比较的都是对象(对象的内存地址)

如果你想改变某一个类的equals,不想用equals比较对象的内存地址,需要重写equals方法

字面量创建String对象

        String s1="abc";//常量池中添加“abc”对象,返回引用地址给s1对象
        String s2="abc";//通过equals方法判断常量池中已有值为abc的对象,返回相同的引用
        System.out.println(s1==s2);
        String s3=new String("def");//在常量池中添加def对象,在堆中创建值为"def"的对象s3,返回指向堆中s3的引用
        String s4=new String("def");//在常量池中已有def对象,在堆中创建值为"def"的对象s4,返回指向堆中s4的引用
        System.out.println(s3==s4);

包装类

static直接通过类名就可以访问

实例变量只有实例化之后才可以使用

类变量不用实例化,直接类名.属性名就可以使用,是类的一部分,也叫做静态变量

用static修饰后的成员具备以下特点

     随着类的加载而加载

     优先于对象存在

     修饰的成员,被所有对象所共享

    不能使用this和super,因为是类的

static只会被执行一次

final:

    final标记的类不能被集成

    标记的方法不能被子类重写

异常

子类的异常不能比父类大

HashSet是set接口的典型实现,当向hashset集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该对象在HashSet中的存储位置。

继承的Collection接口

File只能操作文件本身,不能操作文件内容

BufferedInputStream需要用flush()写入硬盘中

缓冲字节流:

public static void testBufferedInputStream() throws Exception {
        FileInputStream in=new FileInputStream("G:\\aa.txt");
        BufferedInputStream bt=new BufferedInputStream(in);
        byte[] b=new byte[10];
        int len=0;
        while((len=bt.read(b))!=-1){
            System.out.println(new String(b,0,len));
        }
        bt.close();
        in.close();
    }
    public static void testBufferedOutputStream() throws Exception {
        FileOutputStream out=new FileOutputStream("G:\\bb.txt");
        BufferedOutputStream br=new BufferedOutputStream(out);
        String s="ssss";
        br.write(s.getBytes());
        br.flush();//刷到硬盘中
        br.close();
        out.close();
    }

缓冲字符流:

public static void testBufferedReader() throws Exception{
        FileReader r=new FileReader("G:\\aa.txt");
        BufferedReader br=new BufferedReader(r);
        int len=0;
        char[] c=new char[10];
        while((len=br.read(c))!=-1){
            System.out.println(new String(c,0,len));
        }
        br.close();
        r.close();
    }

    public static void testBufferedWriter() throws Exception{
        FileWriter wr=new FileWriter("G:\\cc.txt");
        BufferedWriter br=new BufferedWriter(wr);
        int len=0;
        String c="hello world";
        br.write(c);
        br.close();
        wr.close();
    }

把字节流转换为字符流

转换输入流

public static void testInputStreamReader() throws Exception{
        FileInputStream fs=new FileInputStream("G:\\aa.txt");
        //把字节流转换为字符流
        InputStreamReader in=new InputStreamReader(fs,"UTF-8");//参数1是字节流,参数2是编码
        char[] c=new char[100];
        int len=0;
        while((len=in.read(c))!=-1){
            System.out.println(new String(c,0,len));
        }
        in.close();;
        fs.close();
    }

转换输出流 

public static void testOutputStreamReader() throws Exception{
        FileOutputStream fs=new FileOutputStream("G:\\bb.txt");
        //把字节流转换为字符流
        OutputStreamWriter out=new OutputStreamWriter(fs,"UTF-8");
        out.write("你好");
        out.flush();
        out.close();;
        fs.close();
    }

控制台输入流

 public static void testSystemIn() throws Exception{
        InputStreamReader is=new InputStreamReader(System.in);
        BufferedReader br=new BufferedReader(is);
        String str="";
        while((str=br.readLine())!=null){
            System.out.println(str);
        }
        br.close();
        is.close();
    }

总结

字节流-缓冲流

输入流:InputStream-FileInputStream-BufferedInputStream

输出流:OutputStream-FileOutputStream-BufferedOutputStream

字符流-缓冲流

输入流:Reader-FileReader-BufferedReader

输出流:Writer-FileWriter-BufferedWriter

反射

前提是JVM已经加载过这个类。就可以通过类名来寻找这个类的所有相关信息。

Class类

java.lang.class

Class本身是一个类

 Day s=new Day();
       Class clazz=s.getClass();//包含对象s所属的Day的所有信息

一个Class对象对应的是一个加载到JVM中的一个.class文件

四种创建方式

主要 是前三种

Class c0=Day.class;//通过类名.class创建制定类的class实例
Class c1=s.getClass();//通过一个类的实例对象的getclass()方法
Class c2=Class.forName("Day");//通过class的静态方法来获取类的class的实例,参数时要获取的class实例的类的全路径
        Class clazz=Class.forName("day14.Student");
        Class superclazz=clazz.getSuperclass();
        System.out.println(superclazz.getName());
        Class[] interfaces=clazz.getInterfaces();
        for(Class c:interfaces){
            System.out.println("接口"+c.getName());
        }
        Constructor[] cons=clazz.getConstructors();//获取到类的公有的构造方法
        for(Constructor c:cons){
            //getModifiers()取得方法的修饰符,返回数组,1代表public,返回数组2代表Private
            System.out.println("构造方法名称"+c.getName()+c.getModifiers());
        }
        Constructor[] con=clazz.getDeclaredConstructors();//获取到类的所有的构造方法
        for(Constructor c:con){
            System.out.println("构造方法名称"+c.getName()+c.getModifiers());
        }

通过反射创建一个对象,newInstance()

        Class clazz=Class.forName("day14.Student");
        try{
            Object obj=clazz.newInstance();//相当于调用无参公有的构造方法
            Student stu=(Student)obj;
            Constructor c=clazz.getConstructor(String.class);//指定获取有一个参数并且为String类型的公有构造参数
            Student stu1=(Student)c.newInstance("第一中学");
            Constructor c2=clazz.getDeclaredConstructor(String.class,int.class);
            c2.setAccessible(true);//对私有构造方法解除封装,强制调用
            Student stu2=(Student)c2.newInstance("aaaa",12);
        }catch (Exception e){
            System.out.println(e);
        }

反射机制获取类的属性方法 

            Method[] ss=clazz.getDeclaredMethods();//获取所有方法
            for(Method m:ss){
                System.out.println("方法名"+m.getName());
                System.out.println("返回值类型"+m.getReturnType());
                System.out.println("修饰符"+m.getModifiers());
                Class[] pcs=m.getParameterTypes();
                if(pcs!=null&&pcs.length>0){
                    for(Class pc:pcs){
                        System.out.println("参数类型:"+pc.getName());
                    }
                }
                System.out.println("-------------------------------------");
            }

反射机制调用指定方法

            /*
            不论调用什么方法,都是调用obj的方法,obj对象实际上就是Student
             */
            Constructor con=clazz.getConstructor();//获取无参构造
            Object obj=con.newInstance();//使用无参构造创建对象
            Method c=clazz.getMethod("setInfo", String.class, String.class);
            c.invoke(obj,"张三","第一中学");//参数1是需要实例化的对象,参数2是实际参数
            Method m1=clazz.getDeclaredMethod("test",String.class);
            m1.setAccessible(true);
            m1.invoke(obj,"李四");
            //调用重载方法
            Method m2=clazz.getDeclaredMethod("setInfo", int.class);
            m2.invoke(obj,22);
            //有返回值的方法
            Method m3=clazz.getMethod("getSchool");
            String school=(String)m3.invoke(obj);//调用有返回值的方法

反射机制调用指定属性

            Constructor con=clazz.getConstructor();
            Student stu=(Student)con.newInstance();
            Field f=clazz.getField("school");//获取名称为school的属性
            f.set(stu,"第三中学");//对stu的school属性设置值
            String school=(String)f.get(stu);//获取stu对象的school属性的值
            System.out.println(school);

java动态代理

面对需求:在么一个Java方法上加上两句话,结束加上两句话

如果一个对象想要通过Proxy.newProxyInstance方法被代理,那么这个对象的类一定要有相应的接口

Interface ITestDemo


public interface ITestDemo {
    void test1();
    void test2();
}

class ITestDemoImp1

public class TestDemoImp1 implements ITestDemo {
    @Override
    public void test1(){
        System.out.println("执行test1方法");
    }
    @Override
    public void test2(){
        System.out.println("执行test2方法");
    }
}

通过Proxy 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test2 {
    public static void main(String[] args){
        ITestDemo test=new TestDemoImp1();
        test.test1();
        test.test2();
        InvocationHandler handler=new ProxyDemo(test);
//返回的是成功被代理的对象
        ITestDemo t=(ITestDemo) Proxy.newProxyInstance(handler.getClass().getClassLoader(),test.getClass().getInterfaces(),handler);//第一个参数是代理对象的类加载器,参数2是被代理对象的接口,参数3代理对象
        t.test1();
        t.test2();
    }
}

线程

几核的CPU就代表同一瞬间能处理的任务数

创建线程的第一种方法是集成Thread类

public class TestThread extends Thread {
    @Override
    public void run(){
        System.out.println("多线程运行的代码");
        for(int i=0;i<5;i++){
            System.out.println("这是多线程的逻辑代码"+i);
        }
    }
}

实现Runnable接口实现多线程

public class TestRunnable implements Runnable {
    @Override
    public void run(){
        System.out.println("Runnable多线程运行的代码");
        for(int i=0;i<5;i++){
            System.out.println("这是Runnable多线程的逻辑代码"+i);
        }
    }
}
Thread t3=new Thread(new TestRunnable());
t3.start();

这两种方式的联系与区别

一个是继承Thread,一个是实现接口 Runnable

一般使用实现接口的方式实现多线程

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值