java-乱七八糟

本文详细解析Java中的static关键字,包括static成员变量、static方法、静态代码块的作用和区别,以及static如何影响内存分配和类加载过程。同时,对比static与普通成员变量、方法的使用场景和性能差异,帮助开发者更高效地利用static特性优化代码。

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



static

 

static是用来修饰成员变量和成员方法,也可以形成静态static代码块。

 

静态方法里不能有静态变量,why

不能在方法里声明一个变量为static的。

static修饰的变量,任何一个类的实例对象都可以访问,是共享的。

而方法中声明的变量都是局部的,方法执行完后就要销毁,释放缓存空间的。

 

 

 

修饰符

 

     Public 

     可以从其他类中访问

    

     Abstract 

     本类不能被实例化

    

     Final  

     不能再声明子类

 

构造函数修饰符 

 

     Public

     可以从所有的类中访问

    

     Protected

     只能从自己的类和它的子类中访问

    

     Private

     只能在本类中访问

 

/成员变量修饰符 

 

     Public

     可以从所有的类中访问

    

     Protected

     只能从本类和它的子类中访问

    

     Private

     只能从本类中访问它

    

     Static

     对该类的所有实例只能有一个域值存在

    

     transient

     不是一个对象持久状态的一部份

    

     Volatile

     可以被异步的线程所修改

    

     final

     必须对它赋予初值并且不能修改它

 

局部变量 修饰符

 

     final

     必须对它赋予初值并且不能修改它

 

方法修饰符

 

     Public

     可以从所有的类中访问它

    

     Protected

     只能从本类及其子类中访问它

    

     Private

     只能从本类中访问它

    

     abstract

     没有方法体,属于一个抽象类

    

     final

     子类不能覆盖它

    

     static

     被绑定于类本身而不是类的实例

    

     native

     该方法由其他编程语言实现

      

   

dbms   数据库管理系统(database management system)是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称dbms

  

     

StatementPreparedStatement之间的区别

 

JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement

.代码的可读性和可维护性.

虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:

stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");


perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4)values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();

不用我多说,对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.

.PreparedStatement尽最大可能提高性能.

每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:
insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次
.

当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句
.

.最重要的一点是极大地提高了安全性.


即使到目前为止,仍有一些人连基本的恶义SQL语法都不知道.
String sql = "select * from tb_name where name= '"+varname+"'and passwd='"+varpasswd+"'";
如果我们把[' or '1' = '1]作为varpasswd传入进来.用户名随意,看看会成为什么
?

select * from tb_name = '
随意
' and passwd ='' or '1' = '1';
因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者
:
[';drop table tb_name;]作为varpasswd传入进来,
:
select * from tb_name = '
随意' and passwd ='';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行
.

而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.(前提是数据库本身支持预编译,但上前可能没有什么服务端数据库不支持编译了,只有少数的桌面数据库,就是直接文件访问的那些)只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑
.

上面的几个原因,还不足让你在任何时候都使用PreparedStatement?

 

 

JDBCTMStatement接口提供的executeexecuteQueryexecuteUpdate之间的区别 


Statement
接口提供了三种执行 SQL 语句的方法:executeQueryexecuteUpdate execute。使用哪一个方法由 SQL 语句所产生的内容决定。 

方法executeQuery 
用于产生单个结果集的语句,例如 SELECT 语句。 被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。 

方法executeUpdate 
用于执行 INSERTUPDATE DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE DROP TABLEINSERTUPDATE DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。 

使用executeUpdate方法是因为在createTableCoffees 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。 


方法execute 
用于执行返回多个结果集、多个更新计数或二者组合的语句。因为多数程序员不会需要该高级功能 

execute
方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。当执行某个已存储过程 或动态执行未知 SQL 字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。 
因为方法 execute 处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法 execute 执行该过程后,必须调用方法 getResultSet 获得第一个结果集,然后调用适当的 getXXX 方法获取其中的值。要获得第二个结果集,需要先调用 getMoreResults 方法,然后再调用 getResultSet 方法。如果已知某个过程返回两个更新计数,则首先调用方法 getUpdateCount,然后调用 getMoreResults,并再次调用 getUpdateCount 
对于不知道返回内容,则情况更为复杂。如果结果是 ResultSet 对象,则方法 execute 返回 true;如果结果是 Java int,则返回 false。如果返回 int,则意味着结果是更新计数或执行的语句是 DDL 命令。在调用方法 execute 之后要做的第一件事情是调用 getResultSet getUpdateCount。调用方法 getResultSet 可以获得两个或多个 ResultSet 对象中第一个对象;或调用方法 getUpdateCount 可以获得两个或多个更新计数中第一个更新计数的内容。 
SQL 语句的结果不是结果集时,则方法 getResultSet 将返回 null。这可能意味着结果是一个更新计数或没有其它结果。在这种情况下,判断 null 真正含义的唯一方法是调用方法 getUpdateCount,它将返回一个整数。这个整数为调用语句所影响的行数;如果为 -1 则表示结果是结果集或没有结果。如果方法 getResultSet 已返回 null(表示结果不是 ResultSet 对象),则返回值 -1 表示没有其它结果。也就是说,当下列条件为真时表示没有结果(或没有其它结果): 

((stmt.getResultSet() == null) && (stmt.getUpdateCount() == -1)) 

如果已经调用方法 getResultSet 并处理了它返回的 ResultSet 对象,则有必要调用方法 getMoreResults 以确定是否有其它结果集或更新计数。如果 getMoreResults 返回 true,则需要再次调用 getResultSet 来检索下一个结果集。如上所述,如果 getResultSet 返回 null,则需要调用 getUpdateCount 来检查 null 是表示结果为更新计数还是表示没有其它结果。 

getMoreResults 返回 false 时,它表示该 SQL 语句返回一个更新计数或没有其它结果。因此需要调用方法 getUpdateCount 来检查它是哪一种情况。在这种情况下,当下列条件为真时表示没有其它结果: 

((stmt.getMoreResults() == false) && (stmt.getUpdateCount() ==-1)) 

下面的代码演示了一种方法用来确认已访问调用方法 execute 所产生的全部结果集和更新计数: 


stmt.execute(queryStringWithUnknownResults); 
while (true) { 
int rowCount = stmt.getUpdateCount(); 
if (rowCount > 0) { //
它是更新计数 
System.out.println("Rows changed = " + count); 
stmt.getMoreResults(); 
continue; 

if (rowCount == 0) { // DDL
命令或 0 个更新 
System.out.println(" No rows changed or statement was DDL 
command"); 
stmt.getMoreResults(); 
continue; 


//
执行到这里,证明有一个结果集 
//
或没有其它结果 

ResultSet rs = stmt.getResultSet; 
if (rs != null) { 
. . . //
使用元数据获得关于结果集列的信息 
while (rs.next()) { 
. . . //
处理结果 
stmt.getMoreResults(); 
continue; 

break; //
没有其它结果 

   

 

 

 

PreparedStatementpstmt=conn.prepareStatement(sql);

PreparedStatement 作为执行sql语句的对象,其中后面括号中的(sql)是编写好的,要执行的sql语句
Connection 类是没有无参的prepareStatement方法的

 

PreparedStatement. executeUpdate()

 

JDBCPreparedStatement接口提供的executeexecuteQueryexecuteUpdate之间的区别及用法

 

 

 

PreparedStatement接口提供了三种执行 SQL 语句的方法:executeQueryexecuteUpdate execute。使用哪一个方法由 SQL 语句所产生的内容决定。

      1、方法executeQuery
         用于产生单个结果集的语句,例如 SELECT 语句。 被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。

       2、方法executeUpdate
         用于执行 INSERTUPDATE DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE DROP TABLEINSERTUPDATE DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。

         使用executeUpdate方法是因为在createTableCoffees 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。


        3 方法execute
         用于执行返回多个结果集、多个更新计数或二者组合的语句。也可用于执行 INSERTUPDATE DELETE 语句。

 

用法举例:

1、增加、修改、删除都用execute(),也可用executeUpdate(),针对于INSERTUPDATE DELETE 语句

    publicint addAirEnvironmentPresent(M_AirEnviromentPresentDTO airDTO){
  intindex = 1;
  Stringsql = "insert intoairPresent(airForecastPlace,ForecastTime,TSPvalue,remark) values(?,?,?,?)";
  try{
   ps= conn.prepareStatement(sql);
   ps.setString(index++,airDTO.getAirForecastPlace());
   ps.setString(index++,airDTO.getForecastTime());
   ps.setString(index++,airDTO.getTSPvalue());
   ps.setString(index++,airDTO.getRemark());
   ps.execute();
   
  }catch (SQLException e) {
   e.printStackTrace();
  }
  return1;
 }

2、查询调用executeQuery(),针对于SELECT语句

public ArrayListgetAirEnvironmentPresentAll(){
  ArrayListlist = new ArrayList();
  Stringsql = "select * from airPresent";
  try{
   ps= conn.prepareStatement(sql);
   rs= ps.executeQuery();
   while(rs.next()){
    dto= new M_AirEnviromentPresentDTO();
    dto.setId(rs.getInt("id"));
    dto.setAirForecastPlace(rs.getString("airForecastPlace"));
    dto.setForecastTime(rs.getString("forecastTime"));
    dto.setTSPvalue(rs.getString("tspvalue"));
    dto.setRemark(rs.getString("remark"));
    list.add(dto);
   }
  }catch (SQLException e) {
   e.printStackTrace();
  }
  returnlist;
 }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值