To prevent SQL Injection when the names of objects or columns are entered by the user, I'd recommend as well QUOTENAME() function. Of course, that doesn't remove the good practice of using parametrized queries. Combining both options, you should be safe. If anyone prove me wrong, we can all learn some more.
DECLARE @Table varchar(128) = 'sys.tables; '' SELECT TOP 100* FROM sys.columns'
DECLARE @SQL nvarchar(4000)
SET @SQL = 'SELECT * FROM ' + QUOTENAME(@Table)
PRINT @SQL
EXEC sp_executesql @SQL