xxx_objects.data_object_id differs from object_id after

* truncate table (or alter table truncate partition), unless table/partition is empty
* alter table move (or alter table move partition)
* alter index rebuild (or alter index rebuild partition)
* alter table exchange partition

Alter table move even without TABLESPACE clause (or specifying the same tablespace) physically
moves the table, based on dba_extents.file_id and block_id. But truncate table doesn't move the
table. Think of data_object_id as an ID for the segment. If xxx_objects.data_object_id is null, it
must be an object not associated with a physical segment, such as view, sequence, domain index,
partitioned table/index whose segments are in the individual partitions.

Alter table move lob also changes lob segment's data_object_id.

* How much does data_object_id increment?

Except in case of partition-table exchange, data_object_id is brought up to

select max(data_object_id)+1 from dba_objects

If you just create a new table, it will be assigned an object_id and data_object_id of

select greatest(max(object_id), max(data_object_id)) from dba_objects

If the table has one index, truncate will increment data_object_id by 2 because its index takes the
number one below it. If there's no index, truncate should increment data_object_id by 1 only.

Exchange of a partition with a table swaps their data_object_id's. So don't assume data_object_id's
always go up.

If the table or its partition is already empty, truncating it does not increment data_object_id.
(Rebuilding an empty index or its partition still increments data_object_id, and in case of
online index rebuild, data_object_id could increment by 3 because of "transient" objects created
and dropped during the rebuild.)

* When to use which ID?

You use data_object_id in dbms_rowid, v$bh and x$bh, but object_id in most other cases, such as
v$locked_object. Note that v$segstat, v$segment_statistics and v$logmnr_contents have both.